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

mats petersson via cfe-dev cfe-dev at lists.llvm.org
Thu Jun 22 03:11:28 PDT 2017


On 22 June 2017 at 03:12, Tim Northover via cfe-dev <cfe-dev at lists.llvm.org>
wrote:

> 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'm reasonably sure that the rules of x86-64 is that upper 32-bits of
registers is always zero when operating in 32-bit mode. That certainly
applies to the processors I worked on at AMD when they first came out. A
32-bit operation, no matter what mode the processor is in, will force zeros
in the upper 32 bits. And I think this can still be depended on. What CAN'T
be depended on is that the upper bits remain when switching modes - in
particular, a 16- or 32-bit mode operation may well change something that
you didn't expect to change.

I'd be hugely surprised if the upper bits of RSP isn't zero in this case.
(I'm assuming this is a "user-mode -> user-mode" jump, and not a gate to an
call-gate on the selector).

Obviously, there may be OTHER things that go wrong in the transition (or
just after), without actually knowing more details.

--
Mats

>
> 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.
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170622/bf09c865/attachment.html>


More information about the cfe-dev mailing list