[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