On 2013-01-06 17:03, Stefan Farfeleder wrote:
On Sun, Jan 06, 2013 at 03:59:59PM +0100, Dimitry Andric wrote:
...
The bug also affects ports software, e.g., I also experienced strange
rtorrent segfaults that are now gone.

Can you please try the attached patch, which is a very horrid, atrocious
hack, and will only work for amd64.  Then rebuild libgcc with clang, and
please try if this fixes at least some of the crashes...

This is at least the direction I'm looking at.  It seems that in some
cases with __builtin_eh_return(), llvm does not see that registers can
be clobbered, and it doesn't save and restore them.

After a lot of splitting up of unwind-dw2.c, I arrived at _Unwind_Resume
which when compiled by clang caused the crashes, but when compiled by
gcc ran OK.

Here is a side-by-side overview of the output; sorry for going over any
72-char margin, but this is for illustration.  You can see that gcc
saves most registers on the stack, and restores them just before the eh
return.  Clang does not, at least by default:

GCC OUTPUT                                                      CLANG OUTPUT
=================================================               
=========================================================
_Unwind_Resume:                                                 _Unwind_Resume: 
                        # @_Unwind_Resume
        pushq   %rbp                                                    pushq   
%rbp
        movq    %rsp, %rbp                                              movq    
%rsp, %rbp
        pushq   %r15                                                    pushq   
%rdx
        pushq   %r14                                                    pushq   
%rax
        pushq   %r13                                                    subq    
$528, %rsp              # imm = 0x210
        pushq   %r12                                                    movq    
%rdi, -24(%rbp)
        pushq   %rbx                                                    movq    
%rbp, %rdi
        pushq   %rdx                                                    addq    
$16, %rdi
        pushq   %rax                                                    movq    
8(%rbp), %rdx
        subq    $536, %rsp                                              leaq    
-264(%rbp), %rcx
        movq    %rdi, -584(%rbp)                                        movq    
%rdi, -536(%rbp)        # 8-byte Spill
        movq    8(%rbp), %rax                                           movq    
%rcx, %rdi
        movq    %rax, %rdx                                              movq    
-536(%rbp), %rsi        # 8-byte Reload
        leaq    16(%rbp), %rsi                                          callq   
uw_init_context_1@PLT
        leaq    -336(%rbp), %rdi                                        movabsq 
$240, %rdx
        call    uw_init_context_1@PLT                                   leaq    
-264(%rbp), %rcx
        leaq    -576(%rbp), %rdi                                        leaq    
-504(%rbp), %rsi
        leaq    -336(%rbp), %rsi                                        movq    
%rsi, %rdi
        movl    $240, %edx                                              movq    
%rcx, %rsi
        call    memcpy@PLT                                              callq   
memcpy@PLT
        movq    -584(%rbp), %rax                                        movq    
-24(%rbp), %rcx
        movq    16(%rax), %rax                                          cmpq    
$0, 16(%rcx)
        testq   %rax, %rax                                              jne     
.LBB0_2
        jne     .L59                                                    leaq    
-504(%rbp), %rsi
        leaq    -576(%rbp), %rsi                                        movq    
-24(%rbp), %rdi
        movq    -584(%rbp), %rdi                                        callq   
_Unwind_RaiseException_Phase2@PLT
        call    _Unwind_RaiseException_Phase2@PLT                       movl    
%eax, -508(%rbp)
        movl    %eax, -84(%rbp)                                         jmp     
.LBB0_3
        jmp     .L61                                            .LBB0_2:        
                        # %if.else
.L59:                                                                   leaq    
-504(%rbp), %rsi
        leaq    -576(%rbp), %rsi                                        movq    
-24(%rbp), %rdi
        movq    -584(%rbp), %rdi                                        callq   
_Unwind_ForcedUnwind_Phase2@PLT
        call    _Unwind_ForcedUnwind_Phase2@PLT                         movl    
%eax, -508(%rbp)
        movl    %eax, -84(%rbp)                                 .LBB0_3:        
                        # %if.end
.L61:                                                                   cmpl    
$7, -508(%rbp)
        cmpl    $7, -84(%rbp)                                           je      
.LBB0_5
        je      .L62                                                    callq   
abort@PLT
        call    abort@PLT                                       .LBB0_5:        
                        # %cond.false
.L62:                                                                   jmp     
.LBB0_6
        leaq    -576(%rbp), %rsi                                .LBB0_6:        
                        # %cond.end
        leaq    -336(%rbp), %rdi                                        leaq    
-264(%rbp), %rdi
        call    uw_install_context_1@PLT                                leaq    
-504(%rbp), %rsi
        movq    %rax, -80(%rbp)                                         callq   
uw_install_context_1@PLT
        movq    -424(%rbp), %rax                                        movq    
%rax, -520(%rbp)
        movq    %rax, -72(%rbp)                                         movq    
-352(%rbp), %rsi
        movq    -80(%rbp), %rcx                                         movq    
%rsi, -528(%rbp)
        movq    -72(%rbp), %rax                                         movq    
-520(%rbp), %rsi
        movq    %rax, 8(%rbp,%rcx)                                      movq    
-528(%rbp), %rdi
        movq    -56(%rbp), %rax                                         movq    
%rbp, %rax
        movq    -48(%rbp), %rdx                                         movq    
%rdi, 8(%rax,%rsi)
        movq    -40(%rbp), %rbx                                         leaq    
8(%rax,%rsi), %rcx
        movq    -32(%rbp), %r12                                         addq    
$528, %rsp              # imm = 0x210
        movq    -24(%rbp), %r13                                         popq    
%rax
        movq    -16(%rbp), %r14                                         popq    
%rdx
        movq    -8(%rbp), %r15                                          popq    
%rbp
        leaq    8(%rbp,%rcx), %rcx                                      movq    
%rcx, %rsp
        movq    0(%rbp), %rbp                                           ret     
                        # eh_return, addr: %rcx
        movq    %rcx, %rsp
        ret
Index: contrib/gcc/unwind-dw2.c
===================================================================
--- contrib/gcc/unwind-dw2.c	(revision 244663)
+++ contrib/gcc/unwind-dw2.c	(working copy)
@@ -1448,6 +1448,7 @@ uw_init_context_1 (struct _Unwind_Context *context
     {									 \
       long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
       void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
+      __asm __volatile(" " : : : "r15", "r14", "r13", "r12", "rbx", "rdx", "rax"); \
       __builtin_eh_return (offset, handler);				 \
     }									 \
   while (0)
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to