[cfe-dev] Is force_align_arg_pointer function attribute supported at x86?

Tim Northover via cfe-dev cfe-dev at lists.llvm.org
Wed Jun 21 19:12:12 PDT 2017


On 21 June 2017 at 14:21, Anatol Pomozov <anatol.pomozov at gmail.com> wrote:
> In my example above start_64() is the entry point for 64 mode. 32-bit
> code makes a long jump and does not follow x86_64 stack alignment
> policy. Having __attribute__((force_align_arg_pointer)) in this 64bit
> code is a valid use-case IMO.

The jump has to be made with inline assembly, that puts the whole
control transfer well outside the compiler's purview. That said, I
doubt there'd be strenuous objections to supporting it if patches
turned up.

> I tried to do this in my 32-bit code
>     __asm__ volatile("and %0, %%esp"::"irm"(-16));
>     __asm__ volatile("jmp %0, %1" ::"i"(CODE_SELECTOR), "p"(start_64));
> that compiled into
>
> "and $0xfffffff0,%esp"
> jmp $SELECTOR,start_64
>
> but it does not provide the correct stack alignment.

What goes wrong? I'd wire up a debugger and inspect the state. Some
things that might be useful to probe:

  * Is %esp properly aligned before the far jump?
  * Does the jump involve a change in privilege level, or other weird
x86ism that replaces SP entirely?
  * Does some shim between reaching 64-bit mode and boot_64 mess with it?

The Intel manual also seems to imply that the high bits of %rsp
shouldn't be relied on after a transition to 64-bit mode (from section
3.4.1.1):

"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."

I don't know enough about x86 microarchitectures to say what really
happens (maybe it's zeroed and fine) but random data would definitely
cause problems.

Cheers.

Tim.



More information about the cfe-dev mailing list