clang 3.2 RC2 miscompiles libgcc?
Dimitry Andric
dim at FreeBSD.org
Mon Jan 7 23:21:21 UTC 2013
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 at PLT
leaq -336(%rbp), %rdi movabsq $240, %rdx
call uw_init_context_1 at 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 at PLT callq memcpy at 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 at PLT
call _Unwind_RaiseException_Phase2 at 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 at PLT
call _Unwind_ForcedUnwind_Phase2 at 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 at PLT
call abort at 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 at PLT leaq -504(%rbp), %rsi
movq %rax, -80(%rbp) callq uw_install_context_1 at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: unwind-clobber-1.diff
Type: text/x-diff
Size: 589 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-current/attachments/20130108/5cdd1f41/attachment.diff>
More information about the freebsd-current
mailing list