From: Alan Maguire <alan.maguire@oracle.com>
To: ast@kernel.org, andrii@kernel.org
Cc: daniel@iogearbox.net, eddyz87@gmail.com, jolsa@kernel.org,
ihor.solodrai@linux.dev, yonghong.song@linux.dev,
song@kernel.org, qmo@kernel.org, martin.lau@linux.dev,
memxor@gmail.com, emil@etsalapatis.com, mcgrof@kernel.org,
petr.pavlu@suse.com, tj@kernel.org, kees@kernel.org,
bpf@vger.kernel.org, nathan@kernel.org, nsc@kernel.org,
arnd@arndb.de, puranjay@kernel.org, yatsenko@meta.com,
atenart@kernel.org, ojeda@kernel.org,
linux-modules@vger.kernel.org,
Alan Maguire <alan.maguire@oracle.com>
Subject: [PATCH v2 bpf-next 02/18] libbpf: Add support for BTF kinds LOC[_PARAM|_PROTO|SEC]
Date: Tue, 1 Sep 2026 17:57:41 +0100 [thread overview]
Message-ID: <20260901165757.801449-3-alan.maguire@oracle.com> (raw)
In-Reply-To: <20260901165757.801449-1-alan.maguire@oracle.com>
Add support for new kinds to libbpf. BTF_KIND_LOC_PARAM and
BTF_KIND_LOC_PROTO are dedup-able so add support for their
deduplication, whereas since BTF_KIND_LOCSEC contains a unique
offset it is not. LOC_PARAM is considered a primary type
since it contains no external references; LOC_PROTO is a
reference type consisting of LOC_PARAM references so they
are handled in the primary and reference dedup phases
respectively.
For BTF field iteration, BTF_KIND_LOCSEC needs 2 m_offs[] values
for the associated KIND_FUNC and KIND_LOC_PROTO type ids in
each LOCSEC entry.
Add APIs to add location param, location prototypes and location
sections and btf_is_* tests, data accessors for each.
For BTF distillation we add location info to split BTF.
Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
---
tools/lib/bpf/btf.c | 372 +++++++++++++++++++++++++++++++-
tools/lib/bpf/btf.h | 50 +++++
tools/lib/bpf/btf_dump.c | 9 +
tools/lib/bpf/btf_iter.c | 22 ++
tools/lib/bpf/libbpf.map | 6 +
tools/lib/bpf/libbpf_internal.h | 2 +-
6 files changed, 457 insertions(+), 4 deletions(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index c783359977b4..9449f6f50f18 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -57,6 +57,9 @@ static struct btf_layout layouts[NR_BTF_KINDS] = {
[BTF_KIND_DECL_TAG] = { sizeof(struct btf_decl_tag), 0, 0 },
[BTF_KIND_TYPE_TAG] = { 0, 0, 0 },
[BTF_KIND_ENUM64] = { 0, sizeof(struct btf_enum64), 0 },
+[BTF_KIND_LOC_PARAM] = { sizeof(struct btf_loc_param), sizeof(__u32), 0 },
+[BTF_KIND_LOC_PROTO] = { 0, sizeof(__u32), 0 },
+[BTF_KIND_LOCSEC] = { 0, sizeof(struct btf_loc), 0 },
};
struct btf {
@@ -486,6 +489,12 @@ static int btf_type_size(const struct btf *btf, const struct btf_type *t)
return base_size + vlen * sizeof(struct btf_var_secinfo);
case BTF_KIND_DECL_TAG:
return base_size + sizeof(struct btf_decl_tag);
+ case BTF_KIND_LOC_PARAM:
+ return base_size + sizeof(struct btf_loc_param) + vlen * sizeof(__u32);
+ case BTF_KIND_LOC_PROTO:
+ return base_size + vlen * sizeof(__u32);
+ case BTF_KIND_LOCSEC:
+ return base_size + vlen * sizeof(struct btf_loc);
default:
return btf_type_size_unknown(btf, t);
}
@@ -501,12 +510,15 @@ static void btf_bswap_type_base(struct btf_type *t)
static int btf_bswap_type_rest(struct btf_type *t)
{
struct btf_var_secinfo *v;
+ struct btf_loc_param *lp;
struct btf_enum64 *e64;
struct btf_member *m;
struct btf_array *a;
struct btf_param *p;
struct btf_enum *e;
+ struct btf_loc *l;
__u32 vlen = btf_vlen(t);
+ __u32 *d;
int i;
switch (btf_kind(t)) {
@@ -569,6 +581,23 @@ static int btf_bswap_type_rest(struct btf_type *t)
case BTF_KIND_DECL_TAG:
btf_decl_tag(t)->component_idx = bswap_32(btf_decl_tag(t)->component_idx);
return 0;
+ case BTF_KIND_LOC_PARAM:
+ lp = btf_loc_param(t);
+ lp->flags = bswap_32(lp->flags);
+ for (i = 0, d = (__u32 *)(lp + 1); i < vlen; i++, d++)
+ *d = bswap_32(*d);
+ return 0;
+ case BTF_KIND_LOC_PROTO:
+ for (i = 0, d = btf_loc_proto_params(t); i < vlen; i++, d++)
+ *d = bswap_32(*d);
+ return 0;
+ case BTF_KIND_LOCSEC:
+ for (i = 0, l = btf_locsec_locs(t); i < vlen; i++, l++) {
+ l->func = bswap_32(l->func);
+ l->loc_proto = bswap_32(l->loc_proto);
+ l->offset = bswap_32(l->offset);
+ }
+ return 0;
default:
pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
return -EINVAL;
@@ -745,6 +774,33 @@ static int btf_validate_type(const struct btf *btf, const struct btf_type *t, __
}
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++) {
+ if (!err)
+ err = btf_validate_id(btf, l->func, id);
+ if (!err)
+ err = btf_validate_id(btf, l->loc_proto, id);
+ if (err)
+ return err;
+ }
+ break;
+ }
default:
/* Kind may be represented in kind layout information. */
if (btf_type_size_unknown(btf, t) < 0) {
@@ -3344,6 +3400,208 @@ 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 specified size and flags. Values are
+ * added via btf__add_loc_param_value().
+ *
+ * Returns:
+ * - >0, type ID of newly added BTF type;
+ * - <0, on error.
+ */
+int btf__add_loc_param(struct btf *btf, __u32 size, __u32 flags)
+{
+ struct btf_loc_param *p;
+ struct btf_type *t;
+ int sz, err;
+
+ err = btf_ensure_modifiable(btf);
+ if (err)
+ return libbpf_err(err);
+
+ sz = sizeof(struct btf_type) + sizeof(*p);
+ 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, 0);
+ t->size = size;
+
+ p = btf_loc_param(t);
+ p->flags = flags;
+
+ return btf_commit_type(btf, sz);
+}
+
+int btf__add_loc_param_value(struct btf *btf, __u32 value)
+{
+ struct btf_type *t;
+ int sz, err;
+ __u32 *v;
+
+ /* last type should be BTF_KIND_LOC_PARAM */
+ if (btf->nr_types == 0)
+ return libbpf_err(-EINVAL);
+ t = btf_last_type(btf);
+ if (!btf_is_loc_param(t))
+ return libbpf_err(-EINVAL);
+
+ /* decompose and invalidate raw data */
+ err = btf_ensure_modifiable(btf);
+ if (err)
+ return libbpf_err(err);
+
+ sz = sizeof(value);
+ v = btf_add_type_mem(btf, sz);
+ if (!v)
+ return libbpf_err(-ENOMEM);
+ *v = value;
+
+ /* update parent type's vlen */
+ t = btf_last_type(btf);
+ err = btf_type_inc_vlen(t);
+ if (err)
+ return libbpf_err(err);
+
+ btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
+ return 0;
+}
+
+/*
+ * Append new BTF_KIND_LOC_PROTO
+ *
+ * The prototype is then populated with 0 or more BTF_KIND_LOC_PARAMs via
+ * btf__add_loc_proto_param(); similar to how btf__add_func_param() adds
+ * parameters to a FUNC_PROTO.
+ *
+ * Returns:
+ * - >0, type ID of newly added BTF type;
+ * - <0, on error.
+ */
+int btf__add_loc_proto(struct btf *btf)
+{
+ struct btf_type *t;
+ int err;
+
+ err = btf_ensure_modifiable(btf);
+ if (err)
+ return libbpf_err(err);
+
+ t = btf_add_type_mem(btf, sizeof(struct btf_type));
+ if (!t)
+ return libbpf_err(-ENOMEM);
+
+ t->name_off = 0;
+ t->info = btf_type_info(BTF_KIND_LOC_PROTO, 0, 0);
+ t->size = 0;
+
+ return btf_commit_type(btf, sizeof(struct btf_type));
+}
+
+int btf__add_loc_proto_param(struct btf *btf, __u32 id)
+{
+ struct btf_type *t;
+ int sz, err;
+ __u32 *p;
+
+ if (validate_type_id(id))
+ return libbpf_err(-EINVAL);
+
+ /* last type should be BTF_KIND_LOC_PROTO */
+ if (btf->nr_types == 0)
+ return libbpf_err(-EINVAL);
+ t = btf_last_type(btf);
+ if (!btf_is_loc_proto(t))
+ return libbpf_err(-EINVAL);
+
+ /* decompose and invalidate raw data */
+ err = btf_ensure_modifiable(btf);
+ if (err)
+ return libbpf_err(err);
+
+ sz = sizeof(__u32);
+ p = btf_add_type_mem(btf, sz);
+ if (!p)
+ return libbpf_err(-ENOMEM);
+ *p = id;
+
+ /* update parent type's vlen */
+ t = btf_last_type(btf);
+ err = btf_type_inc_vlen(t);
+ if (err)
+ return libbpf_err(err);
+
+ btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
+ return 0;
+}
+
+int btf__add_locsec(struct btf *btf, const char *name)
+{
+ struct btf_type *t;
+ int name_off = 0;
+ int err;
+
+ err = btf_ensure_modifiable(btf);
+ if (err)
+ return libbpf_err(err);
+
+ t = btf_add_type_mem(btf, sizeof(struct btf_type));
+ if (!t)
+ return libbpf_err(-ENOMEM);
+
+ if (!str_is_empty(name)) {
+ name_off = btf__add_str(btf, name);
+ if (name_off < 0)
+ return name_off;
+ }
+ t->name_off = name_off;
+ t->info = btf_type_info(BTF_KIND_LOCSEC, 0, 0);
+ t->size = 0;
+
+ return btf_commit_type(btf, sizeof(struct btf_type));
+}
+
+int btf__add_locsec_loc(struct btf *btf, __u32 func, __u32 loc_proto,
+ __u32 offset)
+{
+ struct btf_type *t;
+ struct btf_loc *l;
+ int sz, err;
+
+ if (validate_type_id(func) || 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 */
+ err = btf_ensure_modifiable(btf);
+ if (err)
+ return libbpf_err(err);
+
+ sz = sizeof(*l);
+ l = btf_add_type_mem(btf, sz);
+ if (!l)
+ return libbpf_err(-ENOMEM);
+
+ l->func = func;
+ l->loc_proto = loc_proto;
+ l->offset = offset;
+
+ /* update parent type's vlen */
+ t = btf_last_type(btf);
+ err = btf_type_inc_vlen(t);
+ if (err)
+ return libbpf_err(err);
+
+ btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
+ return 0;
+}
+
struct btf_ext_sec_info_param {
__u32 off;
__u32 len;
@@ -4114,8 +4372,8 @@ static struct btf_dedup *btf_dedup_new(struct btf *btf, const struct btf_dedup_o
for (i = 1; i < type_cnt; i++) {
struct btf_type *t = btf_type_by_id(d->btf, i);
- /* VAR and DATASEC are never deduped and are self-canonical */
- if (btf_is_var(t) || btf_is_datasec(t))
+ /* VAR, DATASEC and LOCSEC are never deduped and are self-canonical */
+ if (btf_is_var(t) || btf_is_datasec(t) || btf_is_locsec(t))
d->map[i] = i;
else
d->map[i] = BTF_UNPROCESSED_ID;
@@ -4395,6 +4653,45 @@ static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
btf_is_any_enum(t1) && btf_is_any_enum(t2);
}
+static long btf_hash_loc_param(struct btf_type *t)
+{
+ long h = btf_hash_common(t);
+ __u32 *v = (__u32 *)btf_loc_param(t);
+ int i, vlen = btf_vlen(t);
+
+ for (i = 0; i <= vlen; i++, v++)
+ h = hash_combine(h, *v);
+ return h;
+}
+
+static long btf_hash_loc_proto(struct btf_type *t)
+{
+ __u32 *p = btf_loc_proto_params(t);
+ long h = btf_hash_common(t);
+ int i, vlen = btf_vlen(t);
+
+ for (i = 0; i < vlen; i++, p++)
+ h = hash_combine(h, *p);
+ return h;
+}
+
+static bool btf_equal_loc_param(struct btf_type *t1, struct btf_type *t2)
+{
+ struct btf_loc_param *p1 = btf_loc_param(t1);
+ struct btf_loc_param *p2 = btf_loc_param(t2);
+ __u32 *v1 = (__u32 *)(p1 + 1);
+ __u32 *v2 = (__u32 *)(p2 + 1);
+ int i, vlen = btf_vlen(t1);
+
+ if (!btf_equal_common(t1, t2))
+ return false;
+ for (i = 0; i < vlen; i++, v1++, v2++) {
+ if (*v1 != *v2)
+ return false;
+ }
+ return true;
+}
+
/*
* Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs,
* as referenced type IDs equivalence is established separately during type
@@ -4622,6 +4919,12 @@ static int btf_dedup_prep(struct btf_dedup *d)
case BTF_KIND_FUNC_PROTO:
h = btf_hash_fnproto(t);
break;
+ case BTF_KIND_LOC_PARAM:
+ h = btf_hash_loc_param(t);
+ break;
+ case BTF_KIND_LOC_PROTO:
+ h = btf_hash_loc_proto(t);
+ break;
default:
pr_debug("unknown kind %d for type [%d]\n", btf_kind(t), type_id);
return -EINVAL;
@@ -4664,6 +4967,8 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
case BTF_KIND_DATASEC:
case BTF_KIND_DECL_TAG:
case BTF_KIND_TYPE_TAG:
+ case BTF_KIND_LOC_PROTO:
+ case BTF_KIND_LOCSEC:
return 0;
case BTF_KIND_INT:
@@ -4713,6 +5018,18 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
}
break;
+ case BTF_KIND_LOC_PARAM:
+ h = btf_hash_loc_param(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_loc_param(t, cand)) {
+ new_id = cand_id;
+ break;
+ }
+ }
+ break;
+
default:
return -EINVAL;
}
@@ -5145,6 +5462,13 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
return 1;
}
+ case BTF_KIND_LOC_PARAM:
+ return btf_equal_loc_param(cand_type, canon_type);
+
+ case BTF_KIND_LOC_PROTO:
+ case BTF_KIND_LOCSEC:
+ return 0;
+
default:
return -EINVAL;
}
@@ -5489,6 +5813,41 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
break;
}
+ case BTF_KIND_LOC_PROTO: {
+ __u32 *p1, *p2;
+ __u32 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;
+ vlen = btf_vlen(cand);
+ p1 = btf_loc_proto_params(t);
+ p2 = btf_loc_proto_params(cand);
+ if (vlen == 0) {
+ new_id = cand_id;
+ break;
+ }
+ if (memcmp(p1, p2, vlen * sizeof(__u32)) == 0) {
+ new_id = cand_id;
+ break;
+ }
+ }
+ break;
+ }
+
default:
return -EINVAL;
}
@@ -5970,8 +6329,11 @@ static int btf_add_distilled_type_ids(struct btf_distill *dist, __u32 i)
case BTF_KIND_CONST:
case BTF_KIND_RESTRICT:
case BTF_KIND_VOLATILE:
+ case BTF_KIND_FUNC:
case BTF_KIND_FUNC_PROTO:
case BTF_KIND_TYPE_TAG:
+ case BTF_KIND_LOC_PARAM:
+ case BTF_KIND_LOC_PROTO:
dist->id_map[*id] = *id;
break;
default:
@@ -5997,7 +6359,7 @@ static int btf_add_distilled_type_ids(struct btf_distill *dist, __u32 i)
static int btf_add_distilled_types(struct btf_distill *dist)
{
- bool adding_to_base = dist->pipe.dst->start_id == 1;
+ bool adding_to_base = dist->pipe.dst->base_btf == NULL;
int id = btf__type_cnt(dist->pipe.dst);
struct btf_type *t;
int i, err = 0;
@@ -6065,8 +6427,12 @@ static int btf_add_distilled_types(struct btf_distill *dist)
case BTF_KIND_CONST:
case BTF_KIND_RESTRICT:
case BTF_KIND_VOLATILE:
+ case BTF_KIND_FUNC:
case BTF_KIND_FUNC_PROTO:
case BTF_KIND_TYPE_TAG:
+ case BTF_KIND_LOC_PARAM:
+ case BTF_KIND_LOC_PROTO:
+ case BTF_KIND_LOCSEC:
/* All other types are added to split BTF. */
if (adding_to_base)
continue;
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 587172c0de08..57f12630c5d1 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -274,6 +274,20 @@ LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_typ
LIBBPF_API int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id,
int component_idx);
+/* location construction APIs */
+LIBBPF_API int btf__add_loc_param(struct btf *btf, __u32 size, __u32 flags);
+
+LIBBPF_API int btf__add_loc_param_value(struct btf *btf, __u32 value);
+
+LIBBPF_API int btf__add_loc_proto(struct btf *btf);
+
+LIBBPF_API int btf__add_loc_proto_param(struct btf *btf, __u32 id);
+
+LIBBPF_API int btf__add_locsec(struct btf *btf, const char *name);
+
+LIBBPF_API int btf__add_locsec_loc(struct btf *btf, __u32 func, __u32 loc_proto,
+ __u32 offset);
+
struct btf_dedup_opts {
size_t sz;
/* optional .BTF.ext info to dedup along the main BTF info */
@@ -431,6 +445,12 @@ btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
#define BTF_KIND_DECL_TAG 17 /* Decl Tag */
#define BTF_KIND_TYPE_TAG 18 /* Type Tag */
#define BTF_KIND_ENUM64 19 /* Enum for up-to 64bit values */
+#define BTF_KIND_LOC_PARAM 20 /* Parameter at location */
+#define BTF_KIND_LOC_PROTO 21 /* Parameter set at location */
+#define BTF_KIND_LOCSEC 22 /* Section containing location info */
+
+struct btf_loc_param;
+struct btf_loc;
static inline __u16 btf_kind(const struct btf_type *t)
{
@@ -569,6 +589,21 @@ static inline bool btf_is_any_enum(const struct btf_type *t)
return btf_is_enum(t) || btf_is_enum64(t);
}
+static inline bool btf_is_loc_param(const struct btf_type *t)
+{
+ return btf_kind(t) == BTF_KIND_LOC_PARAM;
+}
+
+static inline bool btf_is_loc_proto(const struct btf_type *t)
+{
+ return btf_kind(t) == BTF_KIND_LOC_PROTO;
+}
+
+static inline bool btf_is_locsec(const struct btf_type *t)
+{
+ return btf_kind(t) == BTF_KIND_LOCSEC;
+}
+
static inline bool btf_kind_core_compat(const struct btf_type *t1,
const struct btf_type *t2)
{
@@ -683,6 +718,21 @@ static inline struct btf_decl_tag *btf_decl_tag(const struct btf_type *t)
return (struct btf_decl_tag *)(t + 1);
}
+static inline struct btf_loc_param *btf_loc_param(const struct btf_type *t)
+{
+ return (struct btf_loc_param *)(t + 1);
+}
+
+static inline __u32 *btf_loc_proto_params(const struct btf_type *t)
+{
+ return (__u32 *)(t + 1);
+}
+
+static inline struct btf_loc *btf_locsec_locs(const struct btf_type *t)
+{
+ return (struct btf_loc *)(t + 1);
+}
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
index 123c448f20c7..fa995c02a170 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:
@@ -609,6 +612,9 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
case BTF_KIND_VAR:
case BTF_KIND_DATASEC:
case BTF_KIND_DECL_TAG:
+ case BTF_KIND_LOC_PARAM:
+ case BTF_KIND_LOC_PROTO:
+ case BTF_KIND_LOCSEC:
d->type_states[id].order_state = ORDERED;
return 0;
@@ -2525,6 +2531,9 @@ static int btf_dump_dump_type_data(struct btf_dump *d,
case BTF_KIND_FUNC:
case BTF_KIND_FUNC_PROTO:
case BTF_KIND_DECL_TAG:
+ case BTF_KIND_LOC_PARAM:
+ case BTF_KIND_LOC_PROTO:
+ case BTF_KIND_LOCSEC:
err = btf_dump_unsupported_data(d, t, id);
break;
case BTF_KIND_INT:
diff --git a/tools/lib/bpf/btf_iter.c b/tools/lib/bpf/btf_iter.c
index 9a6c822c2294..54428e422ec3 100644
--- a/tools/lib/bpf/btf_iter.c
+++ b/tools/lib/bpf/btf_iter.c
@@ -29,6 +29,7 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
case BTF_KIND_FLOAT:
case BTF_KIND_ENUM:
case BTF_KIND_ENUM64:
+ case BTF_KIND_LOC_PARAM:
it->desc = (struct btf_field_desc) {};
break;
case BTF_KIND_FWD:
@@ -71,6 +72,20 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
1, {offsetof(struct btf_var_secinfo, type)}
};
break;
+ case BTF_KIND_LOC_PROTO:
+ it->desc = (struct btf_field_desc) {
+ 0, {},
+ sizeof(__u32),
+ 1, {0}};
+ break;
+ case BTF_KIND_LOCSEC:
+ it->desc = (struct btf_field_desc) {
+ 0, {},
+ sizeof(struct btf_loc),
+ 2, {offsetof(struct btf_loc, func),
+ offsetof(struct btf_loc, loc_proto)}};
+ break;
+
default:
return -EINVAL;
}
@@ -94,6 +109,8 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
case BTF_KIND_DECL_TAG:
case BTF_KIND_TYPE_TAG:
case BTF_KIND_DATASEC:
+ case BTF_KIND_LOC_PARAM:
+ case BTF_KIND_LOC_PROTO:
it->desc = (struct btf_field_desc) {
1, {offsetof(struct btf_type, name_off)}
};
@@ -127,6 +144,11 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
1, {offsetof(struct btf_param, name_off)}
};
break;
+ case BTF_KIND_LOCSEC:
+ it->desc = (struct btf_field_desc) {
+ 1, {offsetof(struct btf_type, name_off)}
+ };
+ break;
default:
return -EINVAL;
}
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 08ab2ea881fb..7f51783df129 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -460,6 +460,12 @@ LIBBPF_1.8.0 {
global:
bpf_program__attach_tracing_multi;
bpf_program__clone;
+ btf__add_loc_param;
+ btf__add_loc_param_value;
+ btf__add_loc_proto;
+ btf__add_loc_proto_param;
+ btf__add_locsec;
+ btf__add_locsec_loc;
btf__find_by_name_kind_own;
btf__new_empty_opts;
} LIBBPF_1.7.0;
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index cb4d96233844..ebac8db1ccfd 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -580,7 +580,7 @@ struct btf_field_desc {
/* member struct size, or zero, if no members */
int m_sz;
/* repeated per-member offsets */
- int m_off_cnt, m_offs[1];
+ int m_off_cnt, m_offs[22];
};
struct btf_field_iter {
--
2.43.5
next prev parent reply other threads:[~2026-09-01 16:58 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 16:57 [PATCH v2 bpf-next 00/18] Support inline functions in BTF Alan Maguire
2026-09-01 16:57 ` [PATCH v2 bpf-next 01/18] btf: Extend UAPI to support BTF location (inline site) info Alan Maguire
2026-09-01 17:17 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-09 22:26 ` Eduard Zingerman
2026-09-11 19:26 ` Jiri Olsa
2026-09-01 16:57 ` Alan Maguire [this message]
2026-09-01 17:11 ` [PATCH v2 bpf-next 02/18] libbpf: Add support for BTF kinds LOC[_PARAM|_PROTO|SEC] sashiko-bot
2026-09-09 22:26 ` Eduard Zingerman
2026-09-01 16:57 ` [PATCH v2 bpf-next 03/18] libbpf: Support moving permuted BTF types into split BTF Alan Maguire
2026-09-01 17:15 ` sashiko-bot
2026-09-01 18:14 ` bot+bpf-ci
2026-09-10 9:37 ` Eduard Zingerman
2026-09-01 16:57 ` [PATCH v2 bpf-next 04/18] selftests/bpf: Test helper support for BTF_KIND_LOC[_PARAM|_PROTO|SEC] Alan Maguire
2026-09-01 17:06 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 05/18] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to field iter tests Alan Maguire
2026-09-01 16:57 ` [PATCH v2 bpf-next 06/18] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to dedup split tests Alan Maguire
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 07/18] selftests/bpf: BTF distill tests to ensure LOC[_PARAM|_PROTO] add to split BTF Alan Maguire
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 08/18] selftests/bpf: Validate that btf__permute transfer works Alan Maguire
2026-09-01 17:16 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 09/18] bpftool: Handle multi-split BTF by supporting multiple base BTFs Alan Maguire
2026-09-01 17:13 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 10/18] bpftool: Document support for multi-split BTF Alan Maguire
2026-09-01 17:12 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 11/18] bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC Alan Maguire
2026-09-01 17:16 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-07 19:30 ` Alexei Starovoitov
2026-09-01 16:57 ` [PATCH v2 bpf-next 12/18] resolve_btfids: Extract inline BTF Alan Maguire
2026-09-01 17:23 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 13/18] kbuild: Add support for BTF inline information Alan Maguire
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 14/18] btf: Make vmlinux, module inline info available in /sys/kernel/btf Alan Maguire
2026-09-07 19:34 ` Alexei Starovoitov
2026-09-07 19:50 ` Alan Maguire
2026-09-07 20:00 ` Alexei Starovoitov
2026-09-01 16:57 ` [PATCH v2 bpf-next 15/18] btf: Support CONFIG_DEBUG_INFO_BTF_INLINE=m Alan Maguire
2026-09-01 17:24 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 16/18] btf: Relocate inline BTF for modules with distilled base BTF Alan Maguire
2026-09-01 17:29 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 17/18] selftests/bpf: Test BTF sysfs inline representations Alan Maguire
2026-09-01 17:22 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 18/18] selftests/bpf: Add a test verifying inline information Alan Maguire
2026-09-01 17:28 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
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=20260901165757.801449-3-alan.maguire@oracle.com \
--to=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=arnd@arndb.de \
--cc=ast@kernel.org \
--cc=atenart@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=kees@kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=mcgrof@kernel.org \
--cc=memxor@gmail.com \
--cc=nathan@kernel.org \
--cc=nsc@kernel.org \
--cc=ojeda@kernel.org \
--cc=petr.pavlu@suse.com \
--cc=puranjay@kernel.org \
--cc=qmo@kernel.org \
--cc=song@kernel.org \
--cc=tj@kernel.org \
--cc=yatsenko@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 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.