[compiler-rt] r277874 - Fix two tests in Win64 ASan
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 8 12:51:43 PDT 2016
On Mon, Aug 8, 2016 at 10:37 AM, Reid Kleckner <rnk at google.com> wrote:
> On Fri, Aug 5, 2016 at 6:53 PM, David Majnemer <david.majnemer at gmail.com>
> wrote:
>
>> On Fri, Aug 5, 2016 at 2:47 PM, Reid Kleckner via llvm-commits <
>> llvm-commits at lists.llvm.org> wrote:
>>
>>> Author: rnk
>>> Date: Fri Aug 5 16:47:46 2016
>>> New Revision: 277874
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=277874&view=rev
>>> Log:
>>> Fix two tests in Win64 ASan
>>>
>>> Go back to intercepting kernel32!RaiseException, and only go for
>>> ntdll!RtlRaiseException if that fails. Fixes throw_and_catch.cc test.
>>>
>>> Work around an issue in LLVM's win64 epilogues. We end up with an
>>> epilogue that looks like this, and it drives the Win64 unwinder crazy
>>> until stack overflow:
>>> call ill_cc!__asan_handle_no_return
>>> xor eax,eax
>>> add rsp,40h // epilogue starts
>>
>> pop rbp // CSR
>>> ud2 // Trap here
>>> ret // Ret?
>>> nop word ptr [rax+rax]
>>> sub rsp,28h // Next function
>>>
>>
>>
>> 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...
>>
>
> 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.
>
> $ cat t.cpp
> void foo();
> int main() { foo(); __builtin_trap(); }
>
> $ clang -S --target=x86_64-windows t.cpp -fno-omit-frame-pointer -o -
> ...
> callq "?foo@@YAXXZ"
> xorl %eax, %eax
> addq $32, %rsp
> popq %rbp
> ud2
> retq
> ...
>
> 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.
>
Hrm, the CoreCLR copy of the x64 unwinder *should* handle this case:
https://github.com/dotnet/coreclr/blob/master/src/unwinder/amd64/unwinder_amd64.cpp#L1304
Our retq is encoded as 0xc3 which is their RET_OP.
Using the same IR but forcing us out of FastISel leaves us with:
callq "?foo@@YAXXZ"
ud2
xorl %eax, %eax
addq $32, %rsp
popq %rbp
retq
The difference is caused by a different selection of terminator in
emitEpligoue (FastISel uses the TRAP while SDAG uses the RETQ).
>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...).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160808/b9b8b229/attachment.html>
More information about the llvm-commits
mailing list