<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 22 June 2017 at 03:12, Tim Northover via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 21 June 2017 at 14:21, Anatol Pomozov <<a href="mailto:anatol.pomozov@gmail.com">anatol.pomozov@gmail.com</a>> wrote:<br>
> In my example above start_64() is the entry point for 64 mode. 32-bit<br>
> code makes a long jump and does not follow x86_64 stack alignment<br>
> policy. Having __attribute__((force_align_<wbr>arg_pointer)) in this 64bit<br>
> code is a valid use-case IMO.<br>
<br>
</span>The jump has to be made with inline assembly, that puts the whole<br>
control transfer well outside the compiler's purview. That said, I<br>
doubt there'd be strenuous objections to supporting it if patches<br>
turned up.<br>
<span class=""><br>
> I tried to do this in my 32-bit code<br>
>     __asm__ volatile("and %0, %%esp"::"irm"(-16));<br>
>     __asm__ volatile("jmp %0, %1" ::"i"(CODE_SELECTOR), "p"(start_64));<br>
> that compiled into<br>
><br>
> "and $0xfffffff0,%esp"<br>
> jmp $SELECTOR,start_64<br>
><br>
> but it does not provide the correct stack alignment.<br>
<br>
</span>What goes wrong? I'd wire up a debugger and inspect the state. Some<br>
things that might be useful to probe:<br>
<br>
  * Is %esp properly aligned before the far jump?<br>
  * Does the jump involve a change in privilege level, or other weird<br>
x86ism that replaces SP entirely?<br>
  * Does some shim between reaching 64-bit mode and boot_64 mess with it?<br>
<br>
The Intel manual also seems to imply that the high bits of %rsp<br>
shouldn't be relied on after a transition to 64-bit mode (from section<br>
3.4.1.1):<br>
<br>
"Because the upper 32 bits of 64-bit general-purpose registers are<br>
undefined in 32-bit modes, the upper 32 bits of any general-purpose<br>
register are not preserved when switching from 64-bit mode to a 32-bit<br>
mode (to protected mode or compatibility mode). Software must not<br>
depend on these bits to maintain a value after a 64-bit to 32-bit mode<br>
switch."<br></blockquote><div><br></div><div>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.<br><br></div><div>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).<br><br></div><div>Obviously, there may be OTHER things that go wrong in the transition (or just after), without actually knowing more details. <br></div><div><br>--<br></div><div>Mats<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I don't know enough about x86 microarchitectures to say what really<br>
happens (maybe it's zeroed and fine) but random data would definitely<br>
cause problems.<br>
<br>
Cheers.<br>
<br>
Tim.<br>
<div class="HOEnZb"><div class="h5">______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div></div>