Skip to content

Commit dc69551

Browse files
mauriciovasquezbernalanakryiko
authored andcommitted
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 <[email protected]> Signed-off-by: Rafael David Tinoco <[email protected]> Signed-off-by: Lorenzo Fontana <[email protected]> Signed-off-by: Leonardo Di Donato <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent a9caaba commit dc69551

File tree

1 file changed

+99
-1
lines changed

1 file changed

+99
-1
lines changed

tools/bpf/bpftool/gen.c

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,10 +1505,108 @@ static int btfgen_record_obj(struct btfgen_info *info, const char *obj_path)
15051505
return err;
15061506
}
15071507

1508+
static int btfgen_remap_id(__u32 *type_id, void *ctx)
1509+
{
1510+
unsigned int *ids = ctx;
1511+
1512+
*type_id = ids[*type_id];
1513+
1514+
return 0;
1515+
}
1516+
15081517
/* Generate BTF from relocation information previously recorded */
15091518
static struct btf *btfgen_get_btf(struct btfgen_info *info)
15101519
{
1511-
return ERR_PTR(-EOPNOTSUPP);
1520+
struct btf *btf_new = NULL;
1521+
unsigned int *ids = NULL;
1522+
unsigned int i, n = btf__type_cnt(info->marked_btf);
1523+
int err = 0;
1524+
1525+
btf_new = btf__new_empty();
1526+
if (!btf_new) {
1527+
err = -errno;
1528+
goto err_out;
1529+
}
1530+
1531+
ids = calloc(n, sizeof(*ids));
1532+
if (!ids) {
1533+
err = -errno;
1534+
goto err_out;
1535+
}
1536+
1537+
/* first pass: add all marked types to btf_new and add their new ids to the ids map */
1538+
for (i = 1; i < n; i++) {
1539+
const struct btf_type *cloned_type, *type;
1540+
const char *name;
1541+
int new_id;
1542+
1543+
cloned_type = btf__type_by_id(info->marked_btf, i);
1544+
1545+
if (cloned_type->name_off != MARKED)
1546+
continue;
1547+
1548+
type = btf__type_by_id(info->src_btf, i);
1549+
1550+
/* add members for struct and union */
1551+
if (btf_is_composite(type)) {
1552+
struct btf_member *cloned_m, *m;
1553+
unsigned short vlen;
1554+
int idx_src;
1555+
1556+
name = btf__str_by_offset(info->src_btf, type->name_off);
1557+
1558+
if (btf_is_struct(type))
1559+
err = btf__add_struct(btf_new, name, type->size);
1560+
else
1561+
err = btf__add_union(btf_new, name, type->size);
1562+
1563+
if (err < 0)
1564+
goto err_out;
1565+
new_id = err;
1566+
1567+
cloned_m = btf_members(cloned_type);
1568+
m = btf_members(type);
1569+
vlen = btf_vlen(cloned_type);
1570+
for (idx_src = 0; idx_src < vlen; idx_src++, cloned_m++, m++) {
1571+
/* add only members that are marked as used */
1572+
if (cloned_m->name_off != MARKED)
1573+
continue;
1574+
1575+
name = btf__str_by_offset(info->src_btf, m->name_off);
1576+
err = btf__add_field(btf_new, name, m->type,
1577+
btf_member_bit_offset(cloned_type, idx_src),
1578+
btf_member_bitfield_size(cloned_type, idx_src));
1579+
if (err < 0)
1580+
goto err_out;
1581+
}
1582+
} else {
1583+
err = btf__add_type(btf_new, info->src_btf, type);
1584+
if (err < 0)
1585+
goto err_out;
1586+
new_id = err;
1587+
}
1588+
1589+
/* add ID mapping */
1590+
ids[i] = new_id;
1591+
}
1592+
1593+
/* second pass: fix up type ids */
1594+
for (i = 1; i < btf__type_cnt(btf_new); i++) {
1595+
struct btf_type *btf_type = (struct btf_type *) btf__type_by_id(btf_new, i);
1596+
1597+
err = btf_type_visit_type_ids(btf_type, btfgen_remap_id, ids);
1598+
if (err)
1599+
goto err_out;
1600+
}
1601+
1602+
free(ids);
1603+
return btf_new;
1604+
1605+
err_out:
1606+
btf__free(btf_new);
1607+
free(ids);
1608+
errno = -err;
1609+
return NULL;
15121610
}
15131611

15141612
/* Create minimized BTF file for a set of BPF objects.

0 commit comments

Comments
 (0)