mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 13:22:23 +00:00
libbpf: Expose btf__align_of() API
Expose BTF API that calculates type alignment requirements. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20191214014341.3442258-7-andriin@fb.com
This commit is contained in:
parent
544402d4b4
commit
3d208f4ca1
@ -278,6 +278,45 @@ done:
|
|||||||
return nelems * size;
|
return nelems * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btf__align_of(const struct btf *btf, __u32 id)
|
||||||
|
{
|
||||||
|
const struct btf_type *t = btf__type_by_id(btf, id);
|
||||||
|
__u16 kind = btf_kind(t);
|
||||||
|
|
||||||
|
switch (kind) {
|
||||||
|
case BTF_KIND_INT:
|
||||||
|
case BTF_KIND_ENUM:
|
||||||
|
return min(sizeof(void *), t->size);
|
||||||
|
case BTF_KIND_PTR:
|
||||||
|
return sizeof(void *);
|
||||||
|
case BTF_KIND_TYPEDEF:
|
||||||
|
case BTF_KIND_VOLATILE:
|
||||||
|
case BTF_KIND_CONST:
|
||||||
|
case BTF_KIND_RESTRICT:
|
||||||
|
return btf__align_of(btf, t->type);
|
||||||
|
case BTF_KIND_ARRAY:
|
||||||
|
return btf__align_of(btf, btf_array(t)->type);
|
||||||
|
case BTF_KIND_STRUCT:
|
||||||
|
case BTF_KIND_UNION: {
|
||||||
|
const struct btf_member *m = btf_members(t);
|
||||||
|
__u16 vlen = btf_vlen(t);
|
||||||
|
int i, align = 1, t;
|
||||||
|
|
||||||
|
for (i = 0; i < vlen; i++, m++) {
|
||||||
|
t = btf__align_of(btf, m->type);
|
||||||
|
if (t <= 0)
|
||||||
|
return t;
|
||||||
|
align = max(align, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return align;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
pr_warn("unsupported BTF_KIND:%u\n", btf_kind(t));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int btf__resolve_type(const struct btf *btf, __u32 type_id)
|
int btf__resolve_type(const struct btf *btf, __u32 type_id)
|
||||||
{
|
{
|
||||||
const struct btf_type *t;
|
const struct btf_type *t;
|
||||||
|
@ -77,6 +77,7 @@ LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
|
|||||||
__u32 id);
|
__u32 id);
|
||||||
LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
|
LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
|
||||||
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
||||||
|
LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id);
|
||||||
LIBBPF_API int btf__fd(const struct btf *btf);
|
LIBBPF_API int btf__fd(const struct btf *btf);
|
||||||
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
|
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
|
||||||
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
||||||
|
@ -752,41 +752,6 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btf_align_of(const struct btf *btf, __u32 id)
|
|
||||||
{
|
|
||||||
const struct btf_type *t = btf__type_by_id(btf, id);
|
|
||||||
__u16 kind = btf_kind(t);
|
|
||||||
|
|
||||||
switch (kind) {
|
|
||||||
case BTF_KIND_INT:
|
|
||||||
case BTF_KIND_ENUM:
|
|
||||||
return min(sizeof(void *), t->size);
|
|
||||||
case BTF_KIND_PTR:
|
|
||||||
return sizeof(void *);
|
|
||||||
case BTF_KIND_TYPEDEF:
|
|
||||||
case BTF_KIND_VOLATILE:
|
|
||||||
case BTF_KIND_CONST:
|
|
||||||
case BTF_KIND_RESTRICT:
|
|
||||||
return btf_align_of(btf, t->type);
|
|
||||||
case BTF_KIND_ARRAY:
|
|
||||||
return btf_align_of(btf, btf_array(t)->type);
|
|
||||||
case BTF_KIND_STRUCT:
|
|
||||||
case BTF_KIND_UNION: {
|
|
||||||
const struct btf_member *m = btf_members(t);
|
|
||||||
__u16 vlen = btf_vlen(t);
|
|
||||||
int i, align = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < vlen; i++, m++)
|
|
||||||
align = max(align, btf_align_of(btf, m->type));
|
|
||||||
|
|
||||||
return align;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
pr_warn("unsupported BTF_KIND:%u\n", btf_kind(t));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
|
static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
|
||||||
const struct btf_type *t)
|
const struct btf_type *t)
|
||||||
{
|
{
|
||||||
@ -794,18 +759,18 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
|
|||||||
int align, i, bit_sz;
|
int align, i, bit_sz;
|
||||||
__u16 vlen;
|
__u16 vlen;
|
||||||
|
|
||||||
align = btf_align_of(btf, id);
|
align = btf__align_of(btf, id);
|
||||||
/* size of a non-packed struct has to be a multiple of its alignment*/
|
/* size of a non-packed struct has to be a multiple of its alignment*/
|
||||||
if (t->size % align)
|
if (align && t->size % align)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
m = btf_members(t);
|
m = btf_members(t);
|
||||||
vlen = btf_vlen(t);
|
vlen = btf_vlen(t);
|
||||||
/* all non-bitfield fields have to be naturally aligned */
|
/* all non-bitfield fields have to be naturally aligned */
|
||||||
for (i = 0; i < vlen; i++, m++) {
|
for (i = 0; i < vlen; i++, m++) {
|
||||||
align = btf_align_of(btf, m->type);
|
align = btf__align_of(btf, m->type);
|
||||||
bit_sz = btf_member_bitfield_size(t, i);
|
bit_sz = btf_member_bitfield_size(t, i);
|
||||||
if (bit_sz == 0 && m->offset % (8 * align) != 0)
|
if (align && bit_sz == 0 && m->offset % (8 * align) != 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,7 +854,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
|
|||||||
fname = btf_name_of(d, m->name_off);
|
fname = btf_name_of(d, m->name_off);
|
||||||
m_sz = btf_member_bitfield_size(t, i);
|
m_sz = btf_member_bitfield_size(t, i);
|
||||||
m_off = btf_member_bit_offset(t, i);
|
m_off = btf_member_bit_offset(t, i);
|
||||||
align = packed ? 1 : btf_align_of(d->btf, m->type);
|
align = packed ? 1 : btf__align_of(d->btf, m->type);
|
||||||
|
|
||||||
btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1);
|
btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1);
|
||||||
btf_dump_printf(d, "\n%s", pfx(lvl + 1));
|
btf_dump_printf(d, "\n%s", pfx(lvl + 1));
|
||||||
@ -907,7 +872,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
|
|||||||
|
|
||||||
/* pad at the end, if necessary */
|
/* pad at the end, if necessary */
|
||||||
if (is_struct) {
|
if (is_struct) {
|
||||||
align = packed ? 1 : btf_align_of(d->btf, id);
|
align = packed ? 1 : btf__align_of(d->btf, id);
|
||||||
btf_dump_emit_bit_padding(d, off, t->size * 8, 0, align,
|
btf_dump_emit_bit_padding(d, off, t->size * 8, 0, align,
|
||||||
lvl + 1);
|
lvl + 1);
|
||||||
}
|
}
|
||||||
|
@ -212,4 +212,5 @@ LIBBPF_0.0.6 {
|
|||||||
LIBBPF_0.0.7 {
|
LIBBPF_0.0.7 {
|
||||||
global:
|
global:
|
||||||
bpf_program__attach;
|
bpf_program__attach;
|
||||||
|
btf__align_of;
|
||||||
} LIBBPF_0.0.6;
|
} LIBBPF_0.0.6;
|
||||||
|
Loading…
Reference in New Issue
Block a user