[cfe-dev] Is force_align_arg_pointer function attribute supported at x86?
Anatol Pomozov via cfe-dev
cfe-dev at lists.llvm.org
Thu Jun 22 13:14:45 PDT 2017
Hi
On Wed, Jun 21, 2017 at 7:12 PM, Tim Northover <t.p.northover at gmail.com> wrote:
> "Because the upper 32 bits of 64-bit general-purpose registers are
> undefined in 32-bit modes, the upper 32 bits of any general-purpose
> register are not preserved when switching from 64-bit mode to a 32-bit
> mode (to protected mode or compatibility mode). Software must not
> depend on these bits to maintain a value after a 64-bit to 32-bit mode
> switch."
This statement describes switching 64->32 bits. In my case the switch
happens the other way 32->64 bits. I expect that the top half of all
registers is initialized with zeros during the switch to 64bits
(citation is needed here).
I checked ABI spec at
https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
it describes stack layout at "3.2.2". Though I found their images and
wording a bit confusing and I did not get clear understanding what is
the alignment requirement for a far jump.
After some experiments I found that the stack pointer should be
aligned to 16-bytes *before* far call. Following example works fine in
vmware, KVM:
and $-16, %esp
call $SELECTOR,start_64
Unfortunately this code crashes Qemu. I believe it is a qemu bug and I
filed it here https://bugs.launchpad.net/bugs/1699867
So I replaced far call with a far jump. Far call puts 4 bytes %cs and
%ip registers to stack, i.e. additional 8 bytes of stack are used. I
replaced the code above with
and $-16, %esp
sub $8, %esp
jmp $SELECTOR,start_64
And SSE works fine with qemu, kvm, vmware.
It solves my original problem, thanks everyone for the help. But if
you folks decide to enable __attribute__((force_align_arg_pointer)) at
x86_64 to make this situation a bit simpler and get into parity with
GCC then I fully support you.
More information about the cfe-dev
mailing list