Open jonathonpenix opened 2 weeks ago
One thought on possible fixes for this: I think GCC does still respect explicit alignment requests here.
So, I think it might be possible to prevent the increased alignment in the first place (and thus the extra padding) by doing something like __attribute__((aligned(__alignof__(struct mystruct))))
where this matters? Ex: https://godbolt.org/z/1jozK4vzx
Describe the bug
The local ISR declaration parser (
CONFIG_ISR_TABLES_LOCAL_DECLARATION=y
) issues incorrect errors about bad IRQ values if any extra padding is inserted by the linker between the.irq_info
and.intList
input sections in the.intList
output section definition (in intlist.ld). Currently, this can happen "naturally" when any opt level besidesCONFIG_SIZE_OPTIMIZATIONS
is specified and we're building with a GCC-based toolchain for AArch64.See "Additional context" for additional info/discussion on what I think is happening.
To Reproduce
This shouldn't be limited to just the one test, but this can be reproduced as below using the Zephyr SDK/Zephyr's tests:
west twister -c -W -p qemu_cortex_a53 -s tests/kernel/interrupt/arch.shared_interrupt.lto -x=CONFIG_SPEED_OPTIMIZATIONS=y
The build should fail (see "Logs and console output" for error).
Expected behavior
We shouldn't produce incorrect/unexpected errors about invalid IRQ numbers that the user did not specify.
Impact
Generally, I think any build will currently fail when the following are true:
CONFIG_ISR_TABLES_LOCAL_DECLARATION=y
is selected-Os
/CONFIG_SIZE_OPTIMIZATIONS
is used.intList
isn't coincidentally aligned on an 8-byte boundary (so the linker will add padding)I think this should also impact some non-AArch64 targets (ex: RISC-V 64) if/when
ISR_TABLES_LOCAL_DECLARATION
is ported, but currently AArch64 is the only impacted target I think. 32bit Arm seems ok experimentally.Logs and console output
west twister -c -W -p qemu_cortex_a53 -s tests/kernel/interrupt/arch.shared_interrupt.lto -x=CONFIG_SPEED_OPTIMIZATIONS=y
produces the following error:Environment (please complete the following information):
Additional context
Using
west twister -c -W -p qemu_cortex_a53 -s tests/kernel/interrupt/arch.shared_interrupt.lto -x=CONFIG_SPEED_OPTIMIZATIONS=y
as an example, I think the problem is that GCC/ld currently add additional padding that the parser doesn't expect/know how to deal with. Relevant snippet from zephyr_pre0.map (note the*fill*
):The
IDT_LIST
region starts at 0xffff8000 (from linker.ld),irq_info
is (reasonably) 20 bytes, and.intList
is padded to an 8-byte boundary (so, a 4-byte fill is added). The parser seems to assume that the section will only be 4-byte aligned (or, that there won't be any padding more generally), so ends parsing the input incorrectly and produces unexpected values for IRQ numbers, etc. which leads to the failure.IIUC, the fill is inserted by ld as GCC seems to increase the alignment of the
.intList
input sections here (/the structs within) to 8-bytes at all opt levels besides-Os
for AArch64. My understanding is that this is done intentionally by GCC, see here for AArch64.Note that this isn't limited to AArch64--see here for RISC-V, for example. Experimentally, GCC seems willing to 8-byte align these sections for AArch64 and RISC-V 64, but 32bit Arm/RISC-V seem ok (4-byte aligned).
FWIW, it doesn't seem like clang/LLVM does this currently (though I suppose it could in the future).