BPF List
 help / color / mirror / Atom feed
* [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

* [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

* 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

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