bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: Alan Maguire <alan.maguire@oracle.com>,
	ast@kernel.org,  daniel@iogearbox.net, andrii@kernel.org
Cc: martin.lau@linux.dev, acme@kernel.org, ttreyer@meta.com,
	 yonghong.song@linux.dev, song@kernel.org,
	john.fastabend@gmail.com,  kpsingh@kernel.org, sdf@fomichev.me,
	haoluo@google.com, jolsa@kernel.org,  qmo@kernel.org,
	ihor.solodrai@linux.dev, david.faust@oracle.com,
	 jose.marchesi@oracle.com, bpf@vger.kernel.org
Subject: Re: [RFC bpf-next 02/15] libbpf: Add support for BTF kinds LOC_PARAM, LOC_PROTO and LOCSEC
Date: Wed, 22 Oct 2025 17:57:32 -0700	[thread overview]
Message-ID: <adb75ea792825e164a4758e40059a677d26694b7.camel@gmail.com> (raw)
In-Reply-To: <20251008173512.731801-3-alan.maguire@oracle.com>

On Wed, 2025-10-08 at 18:34 +0100, Alan Maguire wrote:

[...]

> diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
> index 18907f0fcf9f..0abd7831d6b4 100644
> --- a/tools/lib/bpf/btf.c
> +++ b/tools/lib/bpf/btf.c

[...]

> @@ -588,6 +621,34 @@ static int btf_validate_type(const struct btf *btf, const struct btf_type *t, __

offtopic: we should probably switch this function to use field and string iterators.

>  		}
>  		break;
>  	}
> +	case BTF_KIND_LOC_PARAM:
> +		break;
> +	case BTF_KIND_LOC_PROTO: {
> +		__u32 *p = btf_loc_proto_params(t);
> +
> +		n = btf_vlen(t);
> +		for (i = 0; i < n; i++, p++) {
> +			err = btf_validate_id(btf, *p, id);
> +			if (err)
> +				return err;
> +		}
> +		break;
> +	}
> +	case BTF_KIND_LOCSEC: {
> +		const struct btf_loc *l = btf_locsec_locs(t);
> +
> +		n = btf_vlen(t);
> +		for (i = 0; i < n; i++, l++) {
> +			err = btf_validate_str(btf, l->name_off, "loc name", id);
> +			if (!err)
> +				err = btf_validate_id(btf, l->func_proto, id);
> +			if (!err)
> +				btf_validate_id(btf, l->loc_proto, id);
                              ^^^^
                       Missing `err =`?

> +			if (err)
> +				return err;
> +		}
> +		break;
> +	}
>  	default:
>  		pr_warn("btf: type [%u]: unrecognized kind %u\n", id, kind);
>  		return -EINVAL;
> @@ -2993,6 +3054,183 @@ int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id,
>  	return btf_add_decl_tag(btf, value, ref_type_id, component_idx, 1);
>  }
>  
> +/*
> + * Append new BTF_KIND_LOC_PARAM with either
> + *   - *value* set as __u64 value following btf_type, with info->kflag set to 1
> + *     if *is_value* is true; or
> + *   - *reg* number, *flags* and *offset* set if *is_value* is set to 0, and
> + *    info->kflag set to 0.
> + * Returns:
> + *   -  >0, type ID of newly added BTF type;
> + *   - <0, on error.
> + */
> +int btf__add_loc_param(struct btf *btf, __s32 size, bool is_value, __u64 value,
> +		       __u16 reg, __u16 flags, __s32 offset)

Probably, would be more convenient to have several functions, e.g.:
- btf__add_loc_param_const()
- btf__add_loc_param_reg()
- btf__add_loc_param_deref()

Should `size` be some kind of enum?
E.g. with values like S64, S32, ..., U64.
So the the usage would be like:

  btf__add_loc_param_const(btf, U64, 0xdeadbeef);

Wdyt?

> +{
> +	struct btf_loc_param *p;
> +	struct btf_type *t;
> +	int sz;
> +
> +	if (btf_ensure_modifiable(btf))
> +		return libbpf_err(-ENOMEM);
> +
> +	sz = sizeof(struct btf_type) + sizeof(__u64);
> +	t = btf_add_type_mem(btf, sz);
> +	if (!t)
> +		return libbpf_err(-ENOMEM);
> +
> +	t->name_off = 0;
> +	t->info = btf_type_info(BTF_KIND_LOC_PARAM, 0, is_value);
> +	t->size = size;
> +
> +	p = btf_loc_param(t);
> +
> +	if (is_value) {
> +		p->val_lo32 = value & 0xffffffff;
> +		p->val_hi32 = value >> 32;
> +	} else {
> +		p->reg = reg;
> +		p->flags = flags;
> +		p->offset = offset;
> +	}
> +	return btf_commit_type(btf, sz);
> +}

[...]

> +int btf__add_locsec_loc(struct btf *btf, const char *name, __u32 func_proto, __u32 loc_proto,
> +			__u32 offset)
> +{
> +	struct btf_type *t;
> +	struct btf_loc *l;
> +	int name_off, sz;
> +
> +	if (!name || !name[0])
> +		return libbpf_err(-EINVAL);
> +
> +	if (validate_type_id(func_proto) || validate_type_id(loc_proto))
> +		return libbpf_err(-EINVAL);
> +
> +	/* last type should be BTF_KIND_LOCSEC */
> +	if (btf->nr_types == 0)
> +		return libbpf_err(-EINVAL);
> +	t = btf_last_type(btf);
> +	if (!btf_is_locsec(t))
> +		return libbpf_err(-EINVAL);
> +
> +	/* decompose and invalidate raw data */
> +	if (btf_ensure_modifiable(btf))
> +		return libbpf_err(-ENOMEM);
> +
> +	name_off = btf__add_str(btf, name);
> +	if (name_off < 0)
> +		return name_off;
> +
> +	sz = sizeof(*l);
> +	l = btf_add_type_mem(btf, sz);
> +	if (!l)
> +		return libbpf_err(-ENOMEM);
> +
> +	l->name_off = name_off;
> +	l->func_proto = func_proto;
> +	l->loc_proto = loc_proto;
> +	l->offset = offset;
> +
> +	/* update parent type's vlen */
> +	t = btf_last_type(btf);
> +	btf_type_inc_vlen(t);

Since vlen is only u16, maybe check for overflow and report an error here?

> +
> +	btf->hdr->type_len += sz;
> +	btf->hdr->str_off += sz;
> +	return 0;
> +}
> +
>  struct btf_ext_sec_info_param {
>  	__u32 off;
>  	__u32 len;

[...]

> @@ -5075,6 +5361,45 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
>  		break;
>  	}
>  
> +	case BTF_KIND_LOC_PROTO: {
> +		__u32 *p1, *p2;
> +		__u16 i, vlen;
> +
> +		p1 = btf_loc_proto_params(t);
> +		vlen = btf_vlen(t);
> +
> +		for (i = 0; i < vlen; i++, p1++) {
> +			ref_type_id = btf_dedup_ref_type(d, *p1);
> +			if (ref_type_id < 0)
> +				return ref_type_id;
> +			*p1 = ref_type_id;
> +		}
> +
> +		h = btf_hash_loc_proto(t);
> +		for_each_dedup_cand(d, hash_entry, h) {
> +			cand_id = hash_entry->value;
> +			cand = btf_type_by_id(d->btf, cand_id);
> +			if (!btf_equal_common(t, cand))
> +				continue;

Nit: having btf_equal_loc_proto() would have been more readable here.

> +			vlen = btf_vlen(cand);
> +			p1 = btf_loc_proto_params(t);
> +			p2 = btf_loc_proto_params(cand);
> +			if (vlen == 0) {
> +				new_id = cand_id;
> +				break;
> +			}
> +			for (i = 0; i < vlen; i++, p1++, p2++) {
> +				if (*p1 != *p2)
> +					break;
> +				new_id = cand_id;
> +				break;
> +			}
> +			if (new_id == cand_id)
> +				break;

Why `break` and not `continue`?
Also, BTF_KIND_FUNC_PROTO does not have this special case, why the difference?

> +		}
> +		break;
> +	}
> +
>  	default:
>  		return -EINVAL;
>  	}

[...]

> diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
> index 6388392f49a0..95bdda2f4a2d 100644
> --- a/tools/lib/bpf/btf_dump.c
> +++ b/tools/lib/bpf/btf_dump.c
> @@ -328,6 +328,9 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
>  		case BTF_KIND_ENUM64:
>  		case BTF_KIND_FWD:
>  		case BTF_KIND_FLOAT:
> +		case BTF_KIND_LOC_PARAM:
> +		case BTF_KIND_LOC_PROTO:
> +		case BTF_KIND_LOCSEC:
>  			break;
>  
>  		case BTF_KIND_VOLATILE:
> @@ -339,7 +342,6 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
>  		case BTF_KIND_VAR:
>  		case BTF_KIND_DECL_TAG:
>  		case BTF_KIND_TYPE_TAG:
> -			d->type_states[t->type].referenced = 1;
>  			break;

This change seems unrelated, why is it necessary?

>  
>  		case BTF_KIND_ARRAY: {

[...]


  reply	other threads:[~2025-10-23  0:57 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-08 17:34 [RFC bpf-next 00/15] support inline tracing with BTF Alan Maguire
2025-10-08 17:34 ` [RFC bpf-next 01/15] bpf: Extend UAPI to support location information Alan Maguire
2025-10-16 18:36   ` Andrii Nakryiko
2025-10-17  8:43     ` Alan Maguire
2025-10-20 20:57       ` Andrii Nakryiko
2025-10-23  8:17         ` Alan Maguire
2025-11-05  0:43           ` Andrii Nakryiko
2025-10-23  0:56   ` Eduard Zingerman
2025-10-23  8:35     ` Alan Maguire
2025-10-08 17:34 ` [RFC bpf-next 02/15] libbpf: Add support for BTF kinds LOC_PARAM, LOC_PROTO and LOCSEC Alan Maguire
2025-10-23  0:57   ` Eduard Zingerman [this message]
2025-10-23 19:18   ` Eduard Zingerman
2025-10-23 19:59     ` Eduard Zingerman
2025-10-08 17:34 ` [RFC bpf-next 03/15] libbpf: Add option to retrieve map from old->new ids from btf__dedup() Alan Maguire
2025-10-16 18:39   ` Andrii Nakryiko
2025-10-17  8:56     ` Alan Maguire
2025-10-20 21:03       ` Andrii Nakryiko
2025-10-23  8:25         ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 04/15] libbpf: Fix parsing of multi-split BTF Alan Maguire
2025-10-16 18:36   ` Andrii Nakryiko
2025-10-17 13:47     ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 05/15] bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC Alan Maguire
2025-10-23  0:57   ` Eduard Zingerman
2025-10-23  8:38     ` Alan Maguire
2025-10-23  8:50       ` Eduard Zingerman
2025-10-08 17:35 ` [RFC bpf-next 06/15] bpftool: Handle multi-split BTF by supporting multiple base BTFs Alan Maguire
2025-10-16 18:36   ` Andrii Nakryiko
2025-10-17 13:47     ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 07/15] selftests/bpf: Test helper support for BTF_KIND_LOC[_PARAM|_PROTO|SEC] Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 08/15] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to field iter tests Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 09/15] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to dedup split tests Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 10/15] selftests/bpf: BTF distill tests to ensure LOC[_PARAM|_PROTO] add to split BTF Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 11/15] kbuild: Add support for extra BTF Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 12/15] kbuild, module, bpf: Support CONFIG_DEBUG_INFO_BTF_EXTRA=m Alan Maguire
2025-10-16 18:37   ` Andrii Nakryiko
2025-10-17 13:54     ` Alan Maguire
2025-10-20 21:05       ` Andrii Nakryiko
2025-10-23  0:58   ` Eduard Zingerman
2025-10-23 12:00     ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 13/15] libbpf: add API to load extra BTF Alan Maguire
2025-10-16 18:37   ` Andrii Nakryiko
2025-10-17 13:55     ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 14/15] libbpf: add support for BTF location attachment Alan Maguire
2025-10-16 18:36   ` Andrii Nakryiko
2025-10-17 14:02     ` Alan Maguire
2025-10-20 21:07       ` Andrii Nakryiko
2025-10-08 17:35 ` [RFC bpf-next 15/15] selftests/bpf: Add test tracing inline site using SEC("kloc") Alan Maguire
2025-10-12 23:45 ` [RFC bpf-next 00/15] support inline tracing with BTF Alexei Starovoitov
2025-10-13  7:38   ` Alan Maguire
2025-10-14  0:12     ` Alexei Starovoitov
2025-10-14  9:58       ` Alan Maguire
2025-10-16 18:36         ` Andrii Nakryiko
2025-10-23 14:37           ` Alan Maguire
2025-10-23 16:16             ` Andrii Nakryiko
2025-10-24 11:53               ` Alan Maguire
2025-10-14 11:52       ` Jiri Olsa
2025-10-14 14:55         ` Alan Maguire
2025-10-14 23:04           ` Masami Hiramatsu
2025-10-15 14:17           ` Jiri Olsa
2025-10-15 15:19             ` Alan Maguire
2025-10-15 18:35               ` Jiri Olsa
2025-10-23 22:32 ` Eduard Zingerman
2025-10-24 12:54   ` Alan Maguire

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=adb75ea792825e164a4758e40059a677d26694b7.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=acme@kernel.org \
    --cc=alan.maguire@oracle.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=david.faust@oracle.com \
    --cc=haoluo@google.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=jose.marchesi@oracle.com \
    --cc=kpsingh@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=qmo@kernel.org \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=ttreyer@meta.com \
    --cc=yonghong.song@linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).