Interesting GCC bug
Posted: Sun Jun 20, 2021 2:27 pm
Hi everyone, today i wanna share with you an interesting GCC bug i found.
I was working on FPU initialization in my kernel, and finally got to the point where i needed to use FXSAVE in order to retrieve the FPU MXCSR mask.
Since it was a throw away FPU state i decided to put it on the stack like this:
However, that code would generate GPF at all times, even though the fxsave_region address i logged to the console seemed to be aligned to 32 bytes (0xC0888DA0).
After trying different things (using attribute aligned, moving the variable around, adding * before fxsave_region in the asm statement) i ended up looking at the dissasembly,
which was relatively simple:
Since that code would GPF i had the exact EBP value at the time of the GPF, which was 0xC0888FC4.
As you can see 0xC0888FC4 - 0x218 = 0xC0888DAC, which is 0xC bytes past the address that fxsave_region is actually located at.
For some reason GCC uses a wrong offset to load my stack array.
Not sure what this bug is about, but the workaround i found was to use alignas(32) instead of alignas(16).
I must note that i use GCC 10.1.0.
Since i don't want this to break later on, I'm just going to use kmalloc instead.
If you know anything about this bug please let me know.
I was working on FPU initialization in my kernel, and finally got to the point where i needed to use FXSAVE in order to retrieve the FPU MXCSR mask.
Since it was a throw away FPU state i decided to put it on the stack like this:
Code: Select all
alignas(16) u8 fxsave_region[512] {};
asm volatile ("fxsave %0" : "=m"(fxsave_region));
After trying different things (using attribute aligned, moving the variable around, adding * before fxsave_region in the asm statement) i ended up looking at the dissasembly,
which was relatively simple:
Code: Select all
fxsave [ebp-0x218]
As you can see 0xC0888FC4 - 0x218 = 0xC0888DAC, which is 0xC bytes past the address that fxsave_region is actually located at.
For some reason GCC uses a wrong offset to load my stack array.
Not sure what this bug is about, but the workaround i found was to use alignas(32) instead of alignas(16).
I must note that i use GCC 10.1.0.
Since i don't want this to break later on, I'm just going to use kmalloc instead.
If you know anything about this bug please let me know.