mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-21 00:39:07 +08:00
libbpf: Support appending split BTF in btf__add_btf()
btf__add_btf() currently rejects split BTF sources with -ENOTSUP. This prevents merging types from multiple kernel module BTFs that are all split against the same vmlinux base. Extend btf__add_btf() to handle split BTF sources by: - Replacing the blanket -ENOTSUP with a validation that src and dst share the same base BTF pointer when both are split, returning -EOPNOTSUPP on mismatch. - Computing src_start_id from the source's base to distinguish base type ID references (which must remain unchanged) from split type IDs (which must be remapped to new positions in the destination). - Using src_btf->nr_types instead of btf__type_cnt()-1 for the type count, which is correct for both split and non-split sources. - Skipping base string offsets (< start_str_off) during the string rewrite loop, mirroring the type ID skip pattern. Since src and dst share the same base BTF, base string offsets are already valid and need no remapping. For non-split sources the behavior is identical: src_start_id is 1, the type_id < 1 guard is never true (VOID is already skipped), and the remapping formula reduces to the original. start_str_off is 0 so no string offsets are skipped. Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Alan Maguire <alan.maguire@oracle.com> Link: https://lore.kernel.org/bpf/c00216ed48cf7897078d9645679059d5ebf42738.1772657690.git.josef@toxicpanda.com
This commit is contained in:
committed by
Andrii Nakryiko
parent
67cce78af9
commit
ddb0c14f1b
27
src/btf.c
27
src/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 */
|
||||
|
||||
Reference in New Issue
Block a user