[PATCH 15/31] dwarf_loader: Fix --fixup_silly_bitfields condition check
Arnaldo Carvalho de Melo <[email protected]> Wed, 29 Jul 2026 16:07:15 -0300
| Newsgroups | org.kernel.vger.dwarves,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
From: Arnaldo Carvalho de Melo <[email protected]> The condition for detecting silly bitfields (bitfields that use all bits of their underlying type, e.g. "unsigned int x:32") was inverted since commit 03d9b6ebcac7422f ("dwarf_loader: Fix bitfield fixup logic for DWARF"). The check compared byte_size == 8 * bitfield_size, but byte_size is in bytes and bitfield_size is in bits. For a "unsigned char val:8" silly bitfield: byte_size=1, bitfield_size=8, so 1 == 8*8 = 64 was always false. Fix by multiplying byte_size by 8 to convert to bits before comparing: byte_size * 8 == bitfield_size. Before: $ pahole --fixup_silly_bitfields -C silly test.o unsigned int reserved:32; /* not fixed */ unsigned char flags:8; /* not fixed */ After: $ pahole --fixup_silly_bitfields -C silly test.o unsigned int reserved; /* fixed */ unsigned char flags; /* fixed */ Fixes: 03d9b6ebcac7422f ("dwarf_loader: Fix bitfield fixup logic for DWARF") Cc: Andrii Nakryiko <[email protected]> Reported-by: Sashiko:gemini-3-1-pro-preview Assisted-by: Claude:claude-sonnet-4-5 Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> --- dwarf_loader.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dwarf_loader.c b/dwarf_loader.c index ddf7cdcfd467beb4..ce0bead0e76e1876 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -3798,10 +3798,14 @@ static int class_member__cache_byte_size(struct tag *tag, struct cu *cu, member->byte_offset += member->byte_size; } + /* A "silly" bitfield uses all bits of its underlying type + * (e.g. unsigned char val:8). Convert it to a plain field, + * but only when byte-aligned — in packed structs a full-size + * bitfield can start at a non-zero bit offset. */ if (conf_load && conf_load->fixup_silly_bitfields && - member->byte_size == 8 * member->bitfield_size) { + member->byte_size * 8 == member->bitfield_size && + member->bitfield_offset == 0) { member->bitfield_size = 0; - member->bitfield_offset = 0; } return 0; -- 2.55.0