summaryrefslogtreecommitdiff
path: root/tools/lib
diff options
context:
space:
mode:
authorAndrii Nakryiko <andrii@kernel.org>2026-03-05 14:53:37 -0800
committerAndrii Nakryiko <andrii@kernel.org>2026-03-05 15:03:05 -0800
commit8a2a3aaf90cf671caaca88fe57362c8b169ef392 (patch)
tree34c6353b8d98ea735f4bd2158c8a9ad335d3ef2d /tools/lib
parent4faa1893807cfc9363b19624f8666e07e7e42f59 (diff)
parentfefeeec6123587c6b08884865042988d40405bd2 (diff)
Merge branch 'libbpf-bpftool-support-merging-split-btfs'
Josef Bacik says: ==================== libbpf/bpftool: support merging split BTFs v1: https://lore.kernel.org/bpf/cover.1771605821.git.josef@toxicpanda.com/ v2: https://lore.kernel.org/bpf/cover.1771616227.git.josef@toxicpanda.com/ v3: https://lore.kernel.org/bpf/cover.1771622266.git.josef@toxicpanda.com/ v4: https://lore.kernel.org/bpf/cover.1771625484.git.josef@toxicpanda.com/ v5: https://lore.kernel.org/bpf/cover.1771950922.git.josef@toxicpanda.com/ v1->v2: - Added a btf__dedup() call to btf__add_btf() to ensure that we don't have duplicate types in the merged BTF. v2->v3: - AI review got confused about the UAF comment, so the comment was expanded to clarify the UAF potential. - Fixed potential clobbering of errno in the error path. v3->v4: - Fixed a potential silent corruption pointed out by the AI review bot. v4->v5: - Addressed Andrii's comments for 1/3. - Addressed Alan and Quentin's comments for 2/3. - Addressed Alan's comments for 3/3. - Added my Signed-off-by for the third patch. - Made sure to validate everything still worked. v5->v6: - Fixed the missed is_prefix comment. - Fixed the removed warning about skipping vmlinux. --- Original email --- Hello, I'm extending systing to do introspection on vfio devices, which requires having the structs I need from the kernel available in userspace. Normally these are loadable modules, but in the case of vfio there's multiple structs across multiple modules. Normally you'd do the following to generate your vmlinux.h with a module bpftool btf dump file /sys/kernel/btf/<module> format c \ --base /sys/kernel/btf/vmlinux > vmlinux.h but if you need multiple modules you have to hack together multiple dumps and merge them together. This patch series adds support for merging multiple BTF sources together, so you can do bpftool btf dump file /sys/kernel/btf/<module1> \ file /sys/kernel/btf/<module2> format c \ --base /sys/kernel/btf/vmlinux > vmlinux.h I tested this with my usecase and it works. Thanks, Josef ==================== Link: https://patch.msgid.link/cover.1772657690.git.josef@toxicpanda.com Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/bpf/btf.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 83fe79ffcb8f..40becc964368 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -2004,12 +2004,18 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
{
struct btf_pipe p = { .src = src_btf, .dst = btf };
int data_sz, sz, cnt, i, err, old_strs_len;
+ __u32 src_start_id;
__u32 *off;
void *t;
- /* appending split BTF isn't supported yet */
- if (src_btf->base_btf)
- return libbpf_err(-ENOTSUP);
+ /*
+ * When appending split BTF, the destination must share the same base
+ * BTF so that base type ID references remain valid.
+ */
+ if (src_btf->base_btf && src_btf->base_btf != btf->base_btf)
+ return libbpf_err(-EOPNOTSUPP);
+
+ src_start_id = src_btf->base_btf ? btf__type_cnt(src_btf->base_btf) : 1;
/* deconstruct BTF, if necessary, and invalidate raw_data */
if (btf_ensure_modifiable(btf))
@@ -2021,7 +2027,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
old_strs_len = btf->hdr->str_len;
data_sz = src_btf->hdr->type_len;
- cnt = btf__type_cnt(src_btf) - 1;
+ cnt = src_btf->nr_types;
/* pre-allocate enough memory for new types */
t = btf_add_type_mem(btf, data_sz);
@@ -2060,6 +2066,9 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
if (err)
goto err_out;
while ((str_off = btf_field_iter_next(&it))) {
+ /* don't remap strings from shared base BTF */
+ if (*str_off < src_btf->start_str_off)
+ continue;
err = btf_rewrite_str(&p, str_off);
if (err)
goto err_out;
@@ -2074,11 +2083,11 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
if (!*type_id) /* nothing to do for VOID references */
continue;
- /* we haven't updated btf's type count yet, so
- * btf->start_id + btf->nr_types - 1 is the type ID offset we should
- * add to all newly added BTF types
- */
- *type_id += btf->start_id + btf->nr_types - 1;
+ /* don't remap types from shared base BTF */
+ if (*type_id < src_start_id)
+ continue;
+
+ *type_id += btf->start_id + btf->nr_types - src_start_id;
}
/* go to next type data and type offset index entry */