* [PATCH bpf-next 0/3] BTF inline functionality followups
@ 2026-09-25 9:52 Alan Maguire
2026-09-25 9:52 ` [PATCH bpf-next 1/3] bpf: Verify BTF_KIND_LOC_PARAM vlen, flags Alan Maguire
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Alan Maguire @ 2026-09-25 9:52 UTC (permalink / raw)
To: ast, andrii, eddyz87, qmo
Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau,
memxor, emil, bpf, nsc, puranjay, yatsenko, Alan Maguire
Include additional vlen/flags verification for BTF_KIND_LOC_PARAM
(patch 1), and add function signatures to LOCSEC entries (patch 2),
adjusting test to cover these (patch 3).
Alan Maguire (3):
bpf: Verify BTF_KIND_LOC_PARAM vlen, flags
bpftool: Update func representation to include function signature
selftests/bpf: Fix up bpftool btf dump test for signatures
kernel/bpf/btf.c | 12 +++
tools/bpf/bpftool/btf.c | 100 ++++++++++++++++--
.../bpf/prog_tests/bpftool_btf_dump.c | 14 +--
3 files changed, 111 insertions(+), 15 deletions(-)
--
2.43.5
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH bpf-next 1/3] bpf: Verify BTF_KIND_LOC_PARAM vlen, flags 2026-09-25 9:52 [PATCH bpf-next 0/3] BTF inline functionality followups Alan Maguire @ 2026-09-25 9:52 ` Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 3/3] selftests/bpf: Fix up bpftool btf dump test for signatures Alan Maguire 2 siblings, 0 replies; 8+ messages in thread From: Alan Maguire @ 2026-09-25 9:52 UTC (permalink / raw) To: ast, andrii, eddyz87, qmo Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko, Alan Maguire Ensure that vlen is at least 1, at most 8 for LOC_PARAMs and ensure that flags are a combination of expected values. Fixes: 33c5a3278bdb ("btf: Extend UAPI to support BTF location (inline site) info") Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alan Maguire <alan.maguire@oracle.com> --- kernel/bpf/btf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 5a0179cc1676..dd7ac42649b2 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -4789,6 +4789,18 @@ static s32 btf_loc_param_check_meta(struct btf_verifier_env *env, btf_verifier_log_type(env, t, "Invalid btf_info kind_flag"); return -EINVAL; } + /* All LOC_PARAMs have vlen of at least 1, none have vlen > 8 */ + if (vlen < 1 || vlen > 8) { + btf_verifier_log_type(env, t, "Invalid vlen"); + return -EINVAL; + } + if (p->flags & ~(BTF_LOC_PARAM_SIGNED | BTF_LOC_PARAM_CONST | + BTF_LOC_PARAM_ADDR | BTF_LOC_PARAM_REG | + BTF_LOC_PARAM_DEREF | BTF_LOC_PARAM_OFFSET) || + !p->flags) { + btf_verifier_log_type(env, t, "Invalid flags"); + return -EINVAL; + } btf_verifier_log_type(env, t, NULL); -- 2.43.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature 2026-09-25 9:52 [PATCH bpf-next 0/3] BTF inline functionality followups Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 1/3] bpf: Verify BTF_KIND_LOC_PARAM vlen, flags Alan Maguire @ 2026-09-25 9:52 ` Alan Maguire 2026-09-25 10:36 ` bot+bpf-ci 2026-09-25 12:07 ` Quentin Monnet 2026-09-25 9:52 ` [PATCH bpf-next 3/3] selftests/bpf: Fix up bpftool btf dump test for signatures Alan Maguire 2 siblings, 2 replies; 8+ messages in thread From: Alan Maguire @ 2026-09-25 9:52 UTC (permalink / raw) To: ast, andrii, eddyz87, qmo Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko, Alan Maguire Augment func= output for LOCSEC entries to include a mapping from function signature to where parameters are stored; for example: [290179] LOCSEC 'inline.text' vlen=524941 func='task_pid_nr(tsk [reg0])' func_type_id=136691 loc_proto_type_id=136693 offset=2097226 func='get_current()' func_type_id=136694 loc_proto_type_id=136695 offset=2097247 func='arch_static_branch(key [address 0x2e275e8], branch [const 0x0])' func_type_id=136697 loc_proto_type_id=136700 offset=2097296 Fixes: 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC") Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alan Maguire <alan.maguire@oracle.com> --- tools/bpf/bpftool/btf.c | 100 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 9 deletions(-) diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index e29c8a84e224..6e569ace6add 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -8,6 +8,7 @@ #include <fcntl.h> #include <linux/err.h> #include <stdbool.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -234,8 +235,10 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) (1ULL << bits) - value; } } - snprintf(num, sizeof(num), "0x%llx%s", (unsigned long long)value, - p->flags & BTF_LOC_PARAM_ADDR ? " (addr)" : ""); + snprintf(num, sizeof(num), "%s0x%llx", + p->flags & BTF_LOC_PARAM_ADDR ? "address " : + p->flags & BTF_LOC_PARAM_CONST ? "const " : "", + (unsigned long long)value); } if (i != vlen) { btf_loc_param_raw_str(p, vlen, str, sz); @@ -252,6 +255,87 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) p->flags & BTF_LOC_PARAM_DEREF ? ")" : ""); } +static int btf_locsec_append(char *str, size_t sz, size_t *off, + const char *fmt, ...) +{ + va_list args; + int ret; + + if (!sz || *off >= sz - 1) + return -ENOSPC; + + va_start(args, fmt); + ret = vsnprintf(str + *off, sz - *off, fmt, args); + va_end(args); + if (ret < 0 || (size_t)ret >= sz - *off) { + *off = sz - 1; + return -ENOSPC; + } + *off += ret; + return 0; +} + +static void btf_locsec_func_str(const struct btf *btf, + const struct btf_loc *loc, char *str, size_t sz) +{ + const struct btf_type *func, *func_proto, *loc_proto; + const struct btf_param *params; + const __u32 *loc_params; + const char *name; + __u32 i, vlen; + size_t off = 0; + + if (!sz) + return; + + str[0] = '\0'; + func = btf__type_by_id(btf, loc->func); + if (!func || !btf_is_func(func)) + goto invalid; + + name = btf_str(btf, func->name_off); + func_proto = btf__type_by_id(btf, func->type); + loc_proto = btf__type_by_id(btf, loc->loc_proto); + if (!func_proto || !btf_is_func_proto(func_proto) || + !loc_proto || !btf_is_loc_proto(loc_proto) || + btf_vlen(func_proto) != btf_vlen(loc_proto)) + goto invalid; + + params = (const void *)(func_proto + 1); + loc_params = btf_loc_proto_params(loc_proto); + vlen = btf_vlen(func_proto); + if (btf_locsec_append(str, sz, &off, "%s(", name)) + return; + for (i = 0; i < vlen; i++) { + const struct btf_type *param_loc; + char param_str[256] = {}; + + if (!params[i].type) { + /* Handle varargs func proto, must be last parameter */ + if (i != vlen - 1) + goto invalid; + if (btf_locsec_append(str, sz, &off, "%s...", i ? ", " : "")) + return; + break; + } else if (loc_params[i]) { + param_loc = btf__type_by_id(btf, loc_params[i]); + btf_loc_param_str(param_loc, param_str, sizeof(param_str)); + } else { + snprintf(param_str, sizeof(param_str), "<unavailable>"); + } + + if (btf_locsec_append(str, sz, &off, "%s%s [%s]", + i ? ", " : "", btf_str(btf, params[i].name_off), + param_str)) + return; + } + (void) btf_locsec_append(str, sz, &off, ")"); + return; + +invalid: + snprintf(str, sz, "<invalid>"); +} + static int dump_btf_type(const struct btf *btf, __u32 id, const struct btf_type *t) { @@ -617,22 +701,20 @@ static int dump_btf_type(const struct btf *btf, __u32 id, } for (i = 0; i < vlen; i++, locs++) { - const struct btf_type *f = btf__type_by_id(btf, locs->func); - const char *name = "<invalid>"; + char func_str[1024] = {}; - if (f && btf_is_func(f)) - name = btf_str(btf, f->name_off); + btf_locsec_func_str(btf, locs, func_str, sizeof(func_str)); if (json_output) { jsonw_start_object(w); jsonw_uint_field(w, "func_type_id", locs->func); - jsonw_string_field(w, "name", name); + jsonw_string_field(w, "func", func_str); jsonw_uint_field(w, "loc_proto_type_id", locs->loc_proto); jsonw_uint_field(w, "offset", locs->offset); jsonw_end_object(w); } else { - printf("\n\tname='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", - name, locs->func, locs->loc_proto, locs->offset); + printf("\n\tfunc='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", + func_str, locs->func, locs->loc_proto, locs->offset); } } if (json_output) -- 2.43.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature 2026-09-25 9:52 ` [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature Alan Maguire @ 2026-09-25 10:36 ` bot+bpf-ci 2026-09-25 12:07 ` Quentin Monnet 1 sibling, 0 replies; 8+ messages in thread From: bot+bpf-ci @ 2026-09-25 10:36 UTC (permalink / raw) To: alan.maguire, ast, andrii, eddyz87, qmo Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko, alan.maguire, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, mason, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 5991 bytes --] > commit 46a8924a62f4ce47f7ea0951644e3f0fb4ac14c2 > Author: Alan Maguire <alan.maguire@oracle.com> > > bpftool: Update func representation to include function signature > > Augment func= output for LOCSEC entries to include a mapping from > function signature to where parameters are stored; for example: > > [290179] LOCSEC 'inline.text' vlen=524941 > func='task_pid_nr(tsk [reg0])' func_type_id=136691 loc_proto_type_id=136693 offset=2097226 > func='get_current()' func_type_id=136694 loc_proto_type_id=136695 offset=2097247 > func='arch_static_branch(key [address 0x2e275e8], branch [const 0x0])' func_type_id=136697 loc_proto_type_id=136700 offset=2097296 > > Fixes: 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC") > Suggested-by: Alexei Starovoitov <ast@kernel.org> > Signed-off-by: Alan Maguire <alan.maguire@oracle.com> The changelog only describes the LOCSEC func= change. Does the commit message need to mention the other user-visible output changes? The patch also changes: 1. btf_loc_param_str() now prints "address 0x..." instead of "0x... (addr)", and adds a new "const " prefix. This changes the values= output of every BTF_KIND_LOC_PARAM dump line and the value= output of every BTF_KIND_LOC_PROTO line, not just LOCSEC entries. 2. LOCSEC entries printed name='foo' before this patch, and the JSON key was "name". The patch renames the plain-text field to func= and replaces the JSON "name" key with "func", which now holds a formatted signature string. > diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c > index e29c8a84e224..6e569ace6add 100644 > --- a/tools/bpf/bpftool/btf.c > +++ b/tools/bpf/bpftool/btf.c [ ... ] > @@ -234,8 +235,10 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) > (1ULL << bits) - value; > } > } > - snprintf(num, sizeof(num), "0x%llx%s", (unsigned long long)value, > - p->flags & BTF_LOC_PARAM_ADDR ? " (addr)" : ""); > + snprintf(num, sizeof(num), "%s0x%llx", > + p->flags & BTF_LOC_PARAM_ADDR ? "address " : > + p->flags & BTF_LOC_PARAM_CONST ? "const " : "", > + (unsigned long long)value); > } > if (i != vlen) { > btf_loc_param_raw_str(p, vlen, str, sz); Will negative signed constants now print as "-const 0x16" instead of "const -0x16"? The patch moves the kind label (e.g., "const ") into num as a prefix. The sign, however, still lives in op, and the final format string puts op in front of num: snprintf(str, sz, "%s%s%s%s%s", deref, regs, op, num, deref_close); With no register, op is "-" when negative is true, so the '-' ends up in front of the new label. Take a LOC_PARAM with flags = BTF_LOC_PARAM_CONST | BTF_LOC_PARAM_SIGNED, size 4, and value 0xffffffea (-22). The SIGNED block sets negative = true and value = 0x16. num becomes "const 0x16", op is "-", and the output is: values='-const 0x16' In the new LOCSEC signature it shows up as, for example, "foo(err [-const 0x16])". Before this patch the same parameter printed as "-0x16". The UAPI comment in include/uapi/linux/btf.h says CONST values are interpreted using "size, vlen and _SIGNED flag". The kernel's btf_loc_param_check_meta() accepts CONST|SIGNED. btf_loc_param_str() also has explicit code to handle negative constants ("we need to determine if the value is negative so we can prepend a \"-\""). So this input is expected, for example an inlined call site that passes -EINVAL or -1. Register+offset output ("fbreg - 0x10") is not affected, because neither CONST nor ADDR is set there. [ ... ] > @@ -617,22 +701,20 @@ static int dump_btf_type(const struct btf *btf, __u32 id, > } > > for (i = 0; i < vlen; i++, locs++) { > - const struct btf_type *f = btf__type_by_id(btf, locs->func); > - const char *name = "<invalid>"; > + char func_str[1024] = {}; > > - if (f && btf_is_func(f)) > - name = btf_str(btf, f->name_off); > + btf_locsec_func_str(btf, locs, func_str, sizeof(func_str)); > > if (json_output) { > jsonw_start_object(w); > jsonw_uint_field(w, "func_type_id", locs->func); > - jsonw_string_field(w, "name", name); > + jsonw_string_field(w, "func", func_str); > jsonw_uint_field(w, "loc_proto_type_id", locs->loc_proto); > jsonw_uint_field(w, "offset", locs->offset); > jsonw_end_object(w); > } else { > - printf("\n\tname='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", > - name, locs->func, locs->loc_proto, locs->offset); > + printf("\n\tfunc='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", > + func_str, locs->func, locs->loc_proto, locs->offset); > } > } > if (json_output) Does this commit break the bpftool_btf_dump selftest? At this commit, test_loc_dump() in tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c still compares the output exactly against the old format: "[7] LOC_PARAM ... values='0x123456789abcdef0 (addr)'\n" "[8] LOC_PARAM ... values='0xdeadbeeffeedface'\n" ... "\tname='foo' func_type_id=3 loc_proto_type_id=10 offset=64\n"; ASSERT_OK(compare_text_to_expected(dump, expected), "cmp_loc_dump"); This patch changes all of these lines: the 'address '/'const ' prefixes, and name= becoming func=. The test's FUNC_PROTO also has vlen=5 while the LOC_PROTO has vlen=6. The new btf_locsec_func_str() treats that vlen mismatch as "<invalid>", so cmp_loc_dump fails at this commit. The selftest update in f2a598589f90 ("selftests/bpf: Fix up bpftool btf dump test for signatures") fixes it later in the series. BPF CI runs test_progs per commit, so would it be better to fold that test update into this patch to keep the series bisectable? --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/36122090541 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature 2026-09-25 9:52 ` [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature Alan Maguire 2026-09-25 10:36 ` bot+bpf-ci @ 2026-09-25 12:07 ` Quentin Monnet 2026-09-25 14:58 ` Alan Maguire 1 sibling, 1 reply; 8+ messages in thread From: Quentin Monnet @ 2026-09-25 12:07 UTC (permalink / raw) To: Alan Maguire, ast, andrii, eddyz87 Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko 2026-09-25 10:52 UTC+0100 ~ Alan Maguire <alan.maguire@oracle.com> > Augment func= output for LOCSEC entries to include a mapping from > function signature to where parameters are stored; for example: > > [290179] LOCSEC 'inline.text' vlen=524941 > func='task_pid_nr(tsk [reg0])' func_type_id=136691 loc_proto_type_id=136693 offset=2097226 > func='get_current()' func_type_id=136694 loc_proto_type_id=136695 offset=2097247 > func='arch_static_branch(key [address 0x2e275e8], branch [const 0x0])' func_type_id=136697 loc_proto_type_id=136700 offset=2097296 > > Fixes: 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC") > Suggested-by: Alexei Starovoitov <ast@kernel.org> > Signed-off-by: Alan Maguire <alan.maguire@oracle.com> > --- > tools/bpf/bpftool/btf.c | 100 ++++++++++++++++++++++++++++++++++++---- > 1 file changed, 91 insertions(+), 9 deletions(-) > > diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c > index e29c8a84e224..6e569ace6add 100644 > --- a/tools/bpf/bpftool/btf.c > +++ b/tools/bpf/bpftool/btf.c > @@ -8,6 +8,7 @@ > #include <fcntl.h> > #include <linux/err.h> > #include <stdbool.h> > +#include <stdarg.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > @@ -234,8 +235,10 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) > (1ULL << bits) - value; > } > } > - snprintf(num, sizeof(num), "0x%llx%s", (unsigned long long)value, > - p->flags & BTF_LOC_PARAM_ADDR ? " (addr)" : ""); > + snprintf(num, sizeof(num), "%s0x%llx", > + p->flags & BTF_LOC_PARAM_ADDR ? "address " : > + p->flags & BTF_LOC_PARAM_CONST ? "const " : "", > + (unsigned long long)value); > } > if (i != vlen) { > btf_loc_param_raw_str(p, vlen, str, sz); Thanks Alan! bpf-ci's comment about "-const 0x16" instead of "const -0x16" seems legit, please take a look. > @@ -252,6 +255,87 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) > p->flags & BTF_LOC_PARAM_DEREF ? ")" : ""); > } > > +static int btf_locsec_append(char *str, size_t sz, size_t *off, > + const char *fmt, ...) > +{ > + va_list args; > + int ret; > + > + if (!sz || *off >= sz - 1) > + return -ENOSPC; > + > + va_start(args, fmt); > + ret = vsnprintf(str + *off, sz - *off, fmt, args); Nit: Do you really need vsnprintf()? It looks like you always concatenate, never format any number, so it's probably not the most efficient. I don't mind much, though. > + va_end(args); > + if (ret < 0 || (size_t)ret >= sz - *off) { > + *off = sz - 1; > + return -ENOSPC; It seems unlikely we'll hit this, but maybe warn that the string is truncated in that case, or replace the last characters with "..." or "[truncated]" or something like this?? > + } > + *off += ret; > + return 0; > +} > + > +static void btf_locsec_func_str(const struct btf *btf, > + const struct btf_loc *loc, char *str, size_t sz) > +{ > + const struct btf_type *func, *func_proto, *loc_proto; > + const struct btf_param *params; > + const __u32 *loc_params; > + const char *name; > + __u32 i, vlen; > + size_t off = 0; > + > + if (!sz) > + return; > + > + str[0] = '\0'; > + func = btf__type_by_id(btf, loc->func); > + if (!func || !btf_is_func(func)) > + goto invalid; > + > + name = btf_str(btf, func->name_off); > + func_proto = btf__type_by_id(btf, func->type); > + loc_proto = btf__type_by_id(btf, loc->loc_proto); > + if (!func_proto || !btf_is_func_proto(func_proto) || > + !loc_proto || !btf_is_loc_proto(loc_proto) || > + btf_vlen(func_proto) != btf_vlen(loc_proto)) > + goto invalid; > + > + params = (const void *)(func_proto + 1); > + loc_params = btf_loc_proto_params(loc_proto); > + vlen = btf_vlen(func_proto); > + if (btf_locsec_append(str, sz, &off, "%s(", name)) > + return; > + for (i = 0; i < vlen; i++) { > + const struct btf_type *param_loc; > + char param_str[256] = {}; > + > + if (!params[i].type) { > + /* Handle varargs func proto, must be last parameter */ > + if (i != vlen - 1) > + goto invalid; > + if (btf_locsec_append(str, sz, &off, "%s...", i ? ", " : "")) > + return; > + break; > + } else if (loc_params[i]) { > + param_loc = btf__type_by_id(btf, loc_params[i]); > + btf_loc_param_str(param_loc, param_str, sizeof(param_str)); > + } else { > + snprintf(param_str, sizeof(param_str), "<unavailable>"); > + } > + > + if (btf_locsec_append(str, sz, &off, "%s%s [%s]", > + i ? ", " : "", btf_str(btf, params[i].name_off), > + param_str)) > + return; > + } > + (void) btf_locsec_append(str, sz, &off, ")"); > + return; > + > +invalid: > + snprintf(str, sz, "<invalid>"); > +} > + > static int dump_btf_type(const struct btf *btf, __u32 id, > const struct btf_type *t) > { > @@ -617,22 +701,20 @@ static int dump_btf_type(const struct btf *btf, __u32 id, > } > > for (i = 0; i < vlen; i++, locs++) { > - const struct btf_type *f = btf__type_by_id(btf, locs->func); > - const char *name = "<invalid>"; > + char func_str[1024] = {}; > > - if (f && btf_is_func(f)) > - name = btf_str(btf, f->name_off); > + btf_locsec_func_str(btf, locs, func_str, sizeof(func_str)); > > if (json_output) { > jsonw_start_object(w); > jsonw_uint_field(w, "func_type_id", locs->func); > - jsonw_string_field(w, "name", name); > + jsonw_string_field(w, "func", func_str); Would it be worth keeping the name, too, in the JSON? So that if somebody wants the name only, they don't have to parse it from "func"? > jsonw_uint_field(w, "loc_proto_type_id", locs->loc_proto); > jsonw_uint_field(w, "offset", locs->offset); > jsonw_end_object(w); > } else { > - printf("\n\tname='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", > - name, locs->func, locs->loc_proto, locs->offset); > + printf("\n\tfunc='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", > + func_str, locs->func, locs->loc_proto, locs->offset); > } > } > if (json_output) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature 2026-09-25 12:07 ` Quentin Monnet @ 2026-09-25 14:58 ` Alan Maguire 0 siblings, 0 replies; 8+ messages in thread From: Alan Maguire @ 2026-09-25 14:58 UTC (permalink / raw) To: Quentin Monnet, ast, andrii, eddyz87 Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko On 25/09/2026 13:07, Quentin Monnet wrote: > 2026-09-25 10:52 UTC+0100 ~ Alan Maguire <alan.maguire@oracle.com> >> Augment func= output for LOCSEC entries to include a mapping from >> function signature to where parameters are stored; for example: >> >> [290179] LOCSEC 'inline.text' vlen=524941 >> func='task_pid_nr(tsk [reg0])' func_type_id=136691 loc_proto_type_id=136693 offset=2097226 >> func='get_current()' func_type_id=136694 loc_proto_type_id=136695 offset=2097247 >> func='arch_static_branch(key [address 0x2e275e8], branch [const 0x0])' func_type_id=136697 loc_proto_type_id=136700 offset=2097296 >> >> Fixes: 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC") >> Suggested-by: Alexei Starovoitov <ast@kernel.org> >> Signed-off-by: Alan Maguire <alan.maguire@oracle.com> >> --- >> tools/bpf/bpftool/btf.c | 100 ++++++++++++++++++++++++++++++++++++---- >> 1 file changed, 91 insertions(+), 9 deletions(-) >> >> diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c >> index e29c8a84e224..6e569ace6add 100644 >> --- a/tools/bpf/bpftool/btf.c >> +++ b/tools/bpf/bpftool/btf.c >> @@ -8,6 +8,7 @@ >> #include <fcntl.h> >> #include <linux/err.h> >> #include <stdbool.h> >> +#include <stdarg.h> >> #include <stdio.h> >> #include <stdlib.h> >> #include <string.h> >> @@ -234,8 +235,10 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) >> (1ULL << bits) - value; >> } >> } >> - snprintf(num, sizeof(num), "0x%llx%s", (unsigned long long)value, >> - p->flags & BTF_LOC_PARAM_ADDR ? " (addr)" : ""); >> + snprintf(num, sizeof(num), "%s0x%llx", >> + p->flags & BTF_LOC_PARAM_ADDR ? "address " : >> + p->flags & BTF_LOC_PARAM_CONST ? "const " : "", >> + (unsigned long long)value); >> } >> if (i != vlen) { >> btf_loc_param_raw_str(p, vlen, str, sz); > > > Thanks Alan! > > bpf-ci's comment about "-const 0x16" instead of "const -0x16" seems > legit, please take a look. > Yep, will fix, thanks! > >> @@ -252,6 +255,87 @@ static void btf_loc_param_str(const struct btf_type *t, char *str, size_t sz) >> p->flags & BTF_LOC_PARAM_DEREF ? ")" : ""); >> } >> >> +static int btf_locsec_append(char *str, size_t sz, size_t *off, >> + const char *fmt, ...) >> +{ >> + va_list args; >> + int ret; >> + >> + if (!sz || *off >= sz - 1) >> + return -ENOSPC; >> + >> + va_start(args, fmt); >> + ret = vsnprintf(str + *off, sz - *off, fmt, args); > > > Nit: Do you really need vsnprintf()? It looks like you always > concatenate, never format any number, so it's probably not the most > efficient. I don't mind much, though. > Sure, I'll take a look, might require a few extra append()s but would probably be simpler overall. > >> + va_end(args); >> + if (ret < 0 || (size_t)ret >= sz - *off) { >> + *off = sz - 1; >> + return -ENOSPC; > > > It seems unlikely we'll hit this, but maybe warn that the string is > truncated in that case, or replace the last characters with "..." or > "[truncated]" or something like this?? > yeah we could replace last few chars with ... > >> + } >> + *off += ret; >> + return 0; >> +} >> + >> +static void btf_locsec_func_str(const struct btf *btf, >> + const struct btf_loc *loc, char *str, size_t sz) >> +{ >> + const struct btf_type *func, *func_proto, *loc_proto; >> + const struct btf_param *params; >> + const __u32 *loc_params; >> + const char *name; >> + __u32 i, vlen; >> + size_t off = 0; >> + >> + if (!sz) >> + return; >> + >> + str[0] = '\0'; >> + func = btf__type_by_id(btf, loc->func); >> + if (!func || !btf_is_func(func)) >> + goto invalid; >> + >> + name = btf_str(btf, func->name_off); >> + func_proto = btf__type_by_id(btf, func->type); >> + loc_proto = btf__type_by_id(btf, loc->loc_proto); >> + if (!func_proto || !btf_is_func_proto(func_proto) || >> + !loc_proto || !btf_is_loc_proto(loc_proto) || >> + btf_vlen(func_proto) != btf_vlen(loc_proto)) >> + goto invalid; >> + >> + params = (const void *)(func_proto + 1); >> + loc_params = btf_loc_proto_params(loc_proto); >> + vlen = btf_vlen(func_proto); >> + if (btf_locsec_append(str, sz, &off, "%s(", name)) >> + return; >> + for (i = 0; i < vlen; i++) { >> + const struct btf_type *param_loc; >> + char param_str[256] = {}; >> + >> + if (!params[i].type) { >> + /* Handle varargs func proto, must be last parameter */ >> + if (i != vlen - 1) >> + goto invalid; >> + if (btf_locsec_append(str, sz, &off, "%s...", i ? ", " : "")) >> + return; >> + break; >> + } else if (loc_params[i]) { >> + param_loc = btf__type_by_id(btf, loc_params[i]); >> + btf_loc_param_str(param_loc, param_str, sizeof(param_str)); >> + } else { >> + snprintf(param_str, sizeof(param_str), "<unavailable>"); >> + } >> + >> + if (btf_locsec_append(str, sz, &off, "%s%s [%s]", >> + i ? ", " : "", btf_str(btf, params[i].name_off), >> + param_str)) >> + return; >> + } >> + (void) btf_locsec_append(str, sz, &off, ")"); >> + return; >> + >> +invalid: >> + snprintf(str, sz, "<invalid>"); >> +} >> + >> static int dump_btf_type(const struct btf *btf, __u32 id, >> const struct btf_type *t) >> { >> @@ -617,22 +701,20 @@ static int dump_btf_type(const struct btf *btf, __u32 id, >> } >> >> for (i = 0; i < vlen; i++, locs++) { >> - const struct btf_type *f = btf__type_by_id(btf, locs->func); >> - const char *name = "<invalid>"; >> + char func_str[1024] = {}; >> >> - if (f && btf_is_func(f)) >> - name = btf_str(btf, f->name_off); >> + btf_locsec_func_str(btf, locs, func_str, sizeof(func_str)); >> >> if (json_output) { >> jsonw_start_object(w); >> jsonw_uint_field(w, "func_type_id", locs->func); >> - jsonw_string_field(w, "name", name); >> + jsonw_string_field(w, "func", func_str); > > > Would it be worth keeping the name, too, in the JSON? So that if > somebody wants the name only, they don't have to parse it from "func"? > good idea, will do. > >> jsonw_uint_field(w, "loc_proto_type_id", locs->loc_proto); >> jsonw_uint_field(w, "offset", locs->offset); >> jsonw_end_object(w); >> } else { >> - printf("\n\tname='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", >> - name, locs->func, locs->loc_proto, locs->offset); >> + printf("\n\tfunc='%s' func_type_id=%u loc_proto_type_id=%u offset=%u", >> + func_str, locs->func, locs->loc_proto, locs->offset); >> } >> } >> if (json_output) > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf-next 3/3] selftests/bpf: Fix up bpftool btf dump test for signatures 2026-09-25 9:52 [PATCH bpf-next 0/3] BTF inline functionality followups Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 1/3] bpf: Verify BTF_KIND_LOC_PARAM vlen, flags Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature Alan Maguire @ 2026-09-25 9:52 ` Alan Maguire 2026-09-25 10:36 ` bot+bpf-ci 2 siblings, 1 reply; 8+ messages in thread From: Alan Maguire @ 2026-09-25 9:52 UTC (permalink / raw) To: ast, andrii, eddyz87, qmo Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko, Alan Maguire Now we show a function signature, fix up the test to expect it. Also fix the fact that we did not add the right number of parameters to the FUNC_PROTO, and ensure consts/addresses are prefixed appropriately. Fixes: 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC") Signed-off-by: Alan Maguire <alan.maguire@oracle.com> --- .../selftests/bpf/prog_tests/bpftool_btf_dump.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c index bed506badc75..abc62958b6ed 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c +++ b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c @@ -72,6 +72,7 @@ static struct btf *mk_loc_btf(void) btf__add_func_param(btf, "arg3", 1); btf__add_func_param(btf, "arg4", 1); btf__add_func_param(btf, "arg5", 1); + btf__add_func_param(btf, "arg6", 1); btf__add_func(btf, "foo", BTF_FUNC_STATIC, 2); btf__add_loc_param(btf, 4, BTF_LOC_PARAM_REG); @@ -230,28 +231,29 @@ static void test_loc_dump(const char *btf_path) { const char expected[] = "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED\n" - "[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=5\n" + "[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=6\n" "\t'arg1' type_id=1\n" "\t'arg2' type_id=1\n" "\t'arg3' type_id=1\n" "\t'arg4' type_id=1\n" "\t'arg5' type_id=1\n" + "\t'arg6' type_id=1\n" "[3] FUNC 'foo' type_id=2 linkage=static\n" "[4] LOC_PARAM '(anon)' size=4 flags=0x8 vlen=1 values='reg1'\n" "[5] LOC_PARAM '(anon)' size=8 flags=0x38 vlen=2 values='*(reg2 + 0x10)'\n" "[6] LOC_PARAM '(anon)' size=8 flags=0x29 vlen=2 values='fbreg - 0x10'\n" - "[7] LOC_PARAM '(anon)' size=8 flags=0x6 vlen=2 values='0x123456789abcdef0 (addr)'\n" - "[8] LOC_PARAM '(anon)' size=8 flags=0x2 vlen=2 values='0xdeadbeeffeedface'\n" + "[7] LOC_PARAM '(anon)' size=8 flags=0x6 vlen=2 values='address 0x123456789abcdef0'\n" + "[8] LOC_PARAM '(anon)' size=8 flags=0x2 vlen=2 values='const 0xdeadbeeffeedface'\n" "[9] LOC_PARAM '(anon)' size=8 flags=0x39 vlen=2 values='*(fbreg - 0x20)'\n" "[10] LOC_PROTO '(anon)' vlen=6\n" "\ttype_id=4 value='reg1'\n" "\ttype_id=5 value='*(reg2 + 0x10)'\n" "\ttype_id=6 value='fbreg - 0x10'\n" - "\ttype_id=7 value='0x123456789abcdef0 (addr)'\n" - "\ttype_id=8 value='0xdeadbeeffeedface'\n" + "\ttype_id=7 value='address 0x123456789abcdef0'\n" + "\ttype_id=8 value='const 0xdeadbeeffeedface'\n" "\ttype_id=9 value='*(fbreg - 0x20)'\n" "[11] LOCSEC 'inline.text' vlen=1\n" - "\tname='foo' func_type_id=3 loc_proto_type_id=10 offset=64\n"; + "\tfunc='foo(arg1 [reg1], arg2 [*(reg2 + 0x10)], arg3 [fbreg - 0x10], arg4 [address 0x123456789abcdef0], arg5 [const 0xdeadbeeffeedface], arg6 [*(fbreg - 0x20)])' func_type_id=3 loc_proto_type_id=10 offset=64\n"; char *dump; dump = dump_raw(btf_path); -- 2.43.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 3/3] selftests/bpf: Fix up bpftool btf dump test for signatures 2026-09-25 9:52 ` [PATCH bpf-next 3/3] selftests/bpf: Fix up bpftool btf dump test for signatures Alan Maguire @ 2026-09-25 10:36 ` bot+bpf-ci 0 siblings, 0 replies; 8+ messages in thread From: bot+bpf-ci @ 2026-09-25 10:36 UTC (permalink / raw) To: alan.maguire, ast, andrii, eddyz87, qmo Cc: jolsa, daniel, ihor.solodrai, yonghong.song, song, martin.lau, memxor, emil, bpf, nsc, puranjay, yatsenko, alan.maguire, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, mason, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 1327 bytes --] > selftests/bpf: Fix up bpftool btf dump test for signatures > > Now we show a function signature, fix up the test to expect it. > Also fix the fact that we did not add the right number of parameters > to the FUNC_PROTO, and ensure consts/addresses are prefixed > appropriately. > > Fixes: 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC") > Signed-off-by: Alan Maguire <alan.maguire@oracle.com> Does the Fixes: tag point to the right commit? The commit message references 321562c34d5b ("bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC"), but that commit only added the bpftool feature and did not include the test file being fixed here. The bug being fixed (incorrect FUNC_PROTO vlen=5 when it should be vlen=6 to match the 6 LOC_PARAMs) was actually introduced in commit 3429e01578b6 ("selftests/bpf: Test bpftool dump of BTF location info"), which added the test with only 5 function parameters (arg1-arg5) but 6 LOC_PARAM entries. Should the Fixes: tag be: Fixes: 3429e01578b6 ("selftests/bpf: Test bpftool dump of BTF location info") --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/36122090541 ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-25 14:59 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-25 9:52 [PATCH bpf-next 0/3] BTF inline functionality followups Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 1/3] bpf: Verify BTF_KIND_LOC_PARAM vlen, flags Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 2/3] bpftool: Update func representation to include function signature Alan Maguire 2026-09-25 10:36 ` bot+bpf-ci 2026-09-25 12:07 ` Quentin Monnet 2026-09-25 14:58 ` Alan Maguire 2026-09-25 9:52 ` [PATCH bpf-next 3/3] selftests/bpf: Fix up bpftool btf dump test for signatures Alan Maguire 2026-09-25 10:36 ` bot+bpf-ci
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox