[PATCH v6 bpf-next 03/10] libbpf: use kind layout to compute an unknown kind size

Alan Maguire
2025-12-10T20:33:20Z

This allows BTF parsing to proceed even if we do not know the
kind.

Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
---
tools/lib/bpf/btf.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 737adc560818..4eb0704a0309 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -344,7 +344,29 @@ static int btf_parse_kind_layout_sec(struct btf *btf)
return 0;
}

-static int btf_type_size(const struct btf_type *t)
+/* for unknown kinds, consult kind layout. */
+static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t)
+{
+ int size = sizeof(struct btf_type);
+ struct btf_kind_layout *k = NULL;
+ __u16 vlen = btf_vlen(t);
+ __u8 kind = btf_kind(t);
+
+ if (btf->kind_layout)
+ k = &((struct btf_kind_layout *)btf->kind_layout)[kind];
+
+ if (!k || (void *)k > ((void *)btf->kind_layout + btf->hdr->kind_layout_len)) {
+ pr_debug("Unsupported BTF_KIND: %u\n", btf_kind(t));
+ return -EINVAL;
+ }
+
+ size += k->info_sz;
+ size += vlen * k->elem_sz;
+
+ return size;
+}
+
+static int btf_type_size(const struct btf *btf, const struct btf_type *t)
{
const int base_size = sizeof(struct btf_type);
__u16 vlen = btf_vlen(t);
@@ -380,8 +402,7 @@ static int btf_type_size(const struct btf_type *t)
case BTF_KIND_DECL_TAG:
return base_size + sizeof(struct btf_decl_tag);
default:
- pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
- return -EINVAL;
+ return btf_type_size_unknown(btf, t);
}
}

@@ -480,7 +501,7 @@ static int btf_parse_type_sec(struct btf *btf)
if (btf->swapped_endian)
btf_bswap_type_base(next_type);

- type_size = btf_type_size(next_type);
+ type_size = btf_type_size(btf, next_type);
if (type_size < 0)
return type_size;
if (next_type + type_size > end_type) {
@@ -1976,7 +1997,7 @@ static int btf_add_type(struct btf_pipe *p, const struct btf_type *src_type)
__u32 *str_off;
int sz, err;

- sz = btf_type_size(src_type);
+ sz = btf_type_size(p->src, src_type);
if (sz < 0)
return libbpf_err(sz);

@@ -2058,7 +2079,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
struct btf_field_iter it;
__u32 *type_id, *str_off;

- sz = btf_type_size(t);
+ sz = btf_type_size(src_btf, t);
if (sz < 0) {
/* unlikely, has to be corrupted src_btf */
err = sz;
@@ -5399,7 +5420,7 @@ static int btf_dedup_compact_types(struct btf_dedup *d)
continue;

t = btf__type_by_id(d->btf, id);
- len = btf_type_size(t);
+ len = btf_type_size(d->btf, t);
if (len < 0)
return len;

--
2.43.5