libbpf: Fix btf__align_of() by taking into account field offsets
btf__align_of() is supposed to be return alignment requirement of a requested BTF type. For STRUCT/UNION it doesn't always return correct value, because it calculates alignment only based on field types. But for packed structs this is not enough, we need to also check field offsets and struct size. If field offset isn't aligned according to field type's natural alignment, then struct must be packed. Similarly, if struct size is not a multiple of struct's natural alignment, then struct must be packed as well. This patch fixes this issue precisely by additionally checking these conditions. Fixes: 3d208f4ca111 ("libbpf: Expose btf__align_of() API") Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20221212211505.558851-5-andrii@kernel.org
This commit is contained in:
parent
9d2349740e
commit
25a4481b41
@ -688,8 +688,21 @@ int btf__align_of(const struct btf *btf, __u32 id)
|
||||
if (align <= 0)
|
||||
return libbpf_err(align);
|
||||
max_align = max(max_align, align);
|
||||
|
||||
/* if field offset isn't aligned according to field
|
||||
* type's alignment, then struct must be packed
|
||||
*/
|
||||
if (btf_member_bitfield_size(t, i) == 0 &&
|
||||
(m->offset % (8 * align)) != 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if struct/union size isn't a multiple of its alignment,
|
||||
* then struct must be packed
|
||||
*/
|
||||
if ((t->size % max_align) != 0)
|
||||
return 1;
|
||||
|
||||
return max_align;
|
||||
}
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user