mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
bpftool: Implement btfgen_get_btf()
The last part of the BTFGen algorithm is to create a new BTF object with all the types that were recorded in the previous steps. This function performs two different steps: 1. Add the types to the new BTF object by using btf__add_type(). Some special logic around struct and unions is implemented to only add the members that are really used in the field-based relocations. The type ID on the new and old BTF objects is stored on a map. 2. Fix all the type IDs on the new BTF object by using the IDs saved in the previous step. Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io> Signed-off-by: Rafael David Tinoco <rafael.tinoco@aquasec.com> Signed-off-by: Lorenzo Fontana <lorenzo.fontana@elastic.co> Signed-off-by: Leonardo Di Donato <leonardo.didonato@elastic.co> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20220215225856.671072-6-mauricio@kinvolk.io
This commit is contained in:
parent
a9caaba399
commit
dc695516b6
1 changed files with 99 additions and 1 deletions
|
@ -1505,10 +1505,108 @@ out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int btfgen_remap_id(__u32 *type_id, void *ctx)
|
||||||
|
{
|
||||||
|
unsigned int *ids = ctx;
|
||||||
|
|
||||||
|
*type_id = ids[*type_id];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate BTF from relocation information previously recorded */
|
/* Generate BTF from relocation information previously recorded */
|
||||||
static struct btf *btfgen_get_btf(struct btfgen_info *info)
|
static struct btf *btfgen_get_btf(struct btfgen_info *info)
|
||||||
{
|
{
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
struct btf *btf_new = NULL;
|
||||||
|
unsigned int *ids = NULL;
|
||||||
|
unsigned int i, n = btf__type_cnt(info->marked_btf);
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
btf_new = btf__new_empty();
|
||||||
|
if (!btf_new) {
|
||||||
|
err = -errno;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ids = calloc(n, sizeof(*ids));
|
||||||
|
if (!ids) {
|
||||||
|
err = -errno;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first pass: add all marked types to btf_new and add their new ids to the ids map */
|
||||||
|
for (i = 1; i < n; i++) {
|
||||||
|
const struct btf_type *cloned_type, *type;
|
||||||
|
const char *name;
|
||||||
|
int new_id;
|
||||||
|
|
||||||
|
cloned_type = btf__type_by_id(info->marked_btf, i);
|
||||||
|
|
||||||
|
if (cloned_type->name_off != MARKED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
type = btf__type_by_id(info->src_btf, i);
|
||||||
|
|
||||||
|
/* add members for struct and union */
|
||||||
|
if (btf_is_composite(type)) {
|
||||||
|
struct btf_member *cloned_m, *m;
|
||||||
|
unsigned short vlen;
|
||||||
|
int idx_src;
|
||||||
|
|
||||||
|
name = btf__str_by_offset(info->src_btf, type->name_off);
|
||||||
|
|
||||||
|
if (btf_is_struct(type))
|
||||||
|
err = btf__add_struct(btf_new, name, type->size);
|
||||||
|
else
|
||||||
|
err = btf__add_union(btf_new, name, type->size);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
goto err_out;
|
||||||
|
new_id = err;
|
||||||
|
|
||||||
|
cloned_m = btf_members(cloned_type);
|
||||||
|
m = btf_members(type);
|
||||||
|
vlen = btf_vlen(cloned_type);
|
||||||
|
for (idx_src = 0; idx_src < vlen; idx_src++, cloned_m++, m++) {
|
||||||
|
/* add only members that are marked as used */
|
||||||
|
if (cloned_m->name_off != MARKED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
name = btf__str_by_offset(info->src_btf, m->name_off);
|
||||||
|
err = btf__add_field(btf_new, name, m->type,
|
||||||
|
btf_member_bit_offset(cloned_type, idx_src),
|
||||||
|
btf_member_bitfield_size(cloned_type, idx_src));
|
||||||
|
if (err < 0)
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = btf__add_type(btf_new, info->src_btf, type);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_out;
|
||||||
|
new_id = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add ID mapping */
|
||||||
|
ids[i] = new_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* second pass: fix up type ids */
|
||||||
|
for (i = 1; i < btf__type_cnt(btf_new); i++) {
|
||||||
|
struct btf_type *btf_type = (struct btf_type *) btf__type_by_id(btf_new, i);
|
||||||
|
|
||||||
|
err = btf_type_visit_type_ids(btf_type, btfgen_remap_id, ids);
|
||||||
|
if (err)
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ids);
|
||||||
|
return btf_new;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
btf__free(btf_new);
|
||||||
|
free(ids);
|
||||||
|
errno = -err;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create minimized BTF file for a set of BPF objects.
|
/* Create minimized BTF file for a set of BPF objects.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue