Recently the kernel test robot has reported an ARM-specific BUILD_BUG_ON() in an old and unmaintained wil6210 wireless driver. The problem comes from the structure packing rules of old ARM ABI ('-mabi=apcs-gnu'). For example, the following structure is packed to 18 bytes instead of 16: struct poorly_packed { unsigned int a; unsigned int b; unsigned short c; union { struct { unsigned short d; unsigned int e; } __attribute__((packed)); struct { unsigned short d; unsigned int e; } __attribute__((packed)) inner; }; } __attribute__((packed)); To fit it into 16 bytes, it's required to add packed attribute to the container union as well: struct poorly_packed { unsigned int a; unsigned int b; unsigned short c; union { struct { unsigned short d; unsigned int e; } __attribute__((packed)); struct { unsigned short d; unsigned int e; } __attribute__((packed)) inner; } __attribute__((packed)); } __attribute__((packed)); Thanks to Andrew Pinski of GCC team for sorting the things out at https://gcc.gnu.org/pipermail/gcc/2023-November/242888.html.
Showing the changes to include/uapi/linux (1 of 1 file). Show all
Unified · Split
| @@ -27,7 +27,7 @@ · 26 unmodified lines | |||
| 27 | union { \ | 27 | union { \ |
| 28 | struct { MEMBERS } ATTRS; \ | 28 | struct { MEMBERS } ATTRS; \ |
| 29 | struct TAG { MEMBERS } ATTRS NAME; \ | 29 | struct TAG { MEMBERS } ATTRS NAME; \ |
| 30 | } | 30 | } ATTRS |
| 31 | 31 | ||
| 32 | #ifdef __cplusplus | 32 | #ifdef __cplusplus |
| 33 | /* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ | 33 | /* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ |