<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 8, 2016 at 10:37 AM, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Fri, Aug 5, 2016 at 6:53 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Fri, Aug 5, 2016 at 2:47 PM, Reid Kleckner via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: rnk<br>
Date: Fri Aug  5 16:47:46 2016<br>
New Revision: 277874<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=277874&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=277874&view=rev</a><br>
Log:<br>
Fix two tests in Win64 ASan<br>
<br>
Go back to intercepting kernel32!RaiseException, and only go for<br>
ntdll!RtlRaiseException if that fails. Fixes throw_and_catch.cc test.<br>
<br>
Work around an issue in LLVM's win64 epilogues. We end up with an<br>
epilogue that looks like this, and it drives the Win64 unwinder crazy<br>
until stack overflow:<br>
        call    ill_cc!__asan_handle_no_return<br>
        xor     eax,eax<br>
        add     rsp,40h // epilogue starts </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
        pop     rbp     // CSR<br>
        ud2             // Trap here<br>
        ret             // Ret?<br>
        nop     word ptr [rax+rax]<br>
        sub     rsp,28h // Next function<br></blockquote><div><br></div><div><br></div></span><div>Interesting.  So we started the epilogue but didn't finish it.  Happen to have some IR or C lying around?  I'm curious exactly when we decided that a ud2 between the pop and the ret was a smart move...</div></div></div></div></blockquote><div><br></div></span><div>It's pretty easy to convince LLVM to put the ud2 there, but it's hard to build a test case that will cause the Win64 unwinder to fail in the same way that I observed in this test without the extra conditional control flow that I added. </div><div><br></div><div><div>$ cat t.cpp</div><div>void foo();</div><div>int main() { foo(); __builtin_trap(); }</div></div><div><br></div><div>$ clang -S --target=x86_64-windows t.cpp  -fno-omit-frame-pointer -o -<br></div><div>...</div><div><div>        callq   "?foo@@YAXXZ"</div><div>        xorl    %eax, %eax</div><div>        addq    $32, %rsp</div><div>        popq    %rbp</div><div>        ud2</div><div>        retq</div></div><div>...</div><div><br></div><div>I think the issue is that the faulting PC does not appear to be within a standard epilogue, so the unwinder re-emulates the add 32 and pop rbp.</div></div></div></div>
</blockquote></div><br></div><div class="gmail_extra">Hrm, the CoreCLR copy of the x64 unwinder *should* handle this case: <a href="https://github.com/dotnet/coreclr/blob/master/src/unwinder/amd64/unwinder_amd64.cpp#L1304">https://github.com/dotnet/coreclr/blob/master/src/unwinder/amd64/unwinder_amd64.cpp#L1304</a></div><div class="gmail_extra"><br></div><div class="gmail_extra">Our retq is encoded as 0xc3 which is their RET_OP.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Using the same IR but forcing us out of FastISel leaves us with:</div><div class="gmail_extra"><div class="gmail_extra"><span class="" style="white-space:pre">    </span>callq<span class="" style="white-space:pre">     </span>"?foo@@YAXXZ"</div><div class="gmail_extra"><span class="" style="white-space:pre">      </span>ud2</div><div class="gmail_extra"><span class="" style="white-space:pre">  </span>xorl<span class="" style="white-space:pre">      </span>%eax, %eax</div><div class="gmail_extra"><span class="" style="white-space:pre">   </span>addq<span class="" style="white-space:pre">      </span>$32, %rsp</div><div class="gmail_extra"><span class="" style="white-space:pre">    </span>popq<span class="" style="white-space:pre">      </span>%rbp</div><div class="gmail_extra"><span class="" style="white-space:pre"> </span>retq</div><div><br></div><div>The difference is caused by a different selection of terminator in emitEpligoue (FastISel uses the TRAP while SDAG uses the RETQ).</div><div><br></div><div>From reading the x64 ABI docs, I cannot find where we strongly violated a constraint.  My only guess is that it doesn't like us partially unwinding a frame function before performing the trap (something along the lines of the unwinder _expecting_ to see an SP adjustment but seeing nothing but the ret...).</div></div></div>