On 9 November 2010 16:42, Jay Foad <jay.foad at gmail.com>
wrote:> Hi,
>
> On Ubuntu Linux/x86_64, I get:
>
> $ cat t.c
> #include <stdio.h>
> __thread int i = 7;
> int main() { printf("%d\n", i); }
> $ clang -o t t.c
> $ ./t
> Segmentation fault
>
> (gdb) disas
> Dump of assembler code for function main:
> 0x0000000000400560 <+0>: push %rbp
> 0x0000000000400561 <+1>: mov %rsp,%rbp
> 0x0000000000400564 <+4>: sub $0x10,%rsp
> 0x0000000000400568 <+8>: movl $0x0,-0x4(%rbp)
> => 0x000000000040056f <+15>: mov %fs:0x402034,%esi
> 0x0000000000400577 <+23>: xor %al,%al
> 0x0000000000400579 <+25>: mov $0x40066c,%edi
> 0x000000000040057e <+30>: callq 0x4006e0 <printf at plt>
> 0x0000000000400583 <+35>: mov %eax,-0x8(%rbp)
> 0x0000000000400586 <+38>: mov -0x4(%rbp),%eax
> 0x0000000000400589 <+41>: add $0x10,%rsp
> 0x000000000040058d <+45>: pop %rbp
> 0x000000000040058e <+46>: retq
> End of assembler dump.
> (gdb) p $fs
> $1 = 0
> (gdb) p *(int*)0x402034
> $2 = 0
>
> I don't really understand why it's segfaulting here, but presumably
> it's something to do with thread-local storage not being set up
> properly?
>
> I'm using Clang and LLVM from svn trunk, updated a few minutes ago.
The problem seems to be with Clang's assembler:
$ clang -S -o t.s t.c
$ clang -c -o bad.o t.s
$ gcc -o bad bad.o
$ ./bad
Segmentation fault
$ gcc -c -o good.o t.s
$ gcc -o good good.o
$ ./good
7
The only difference here is whether t.s was assembled by clang or by gcc.
Delving a bit deeper, the difference seems to be that symbol "i" in
the assembler source:
.type i, at object # @i
.section .tdata,"awT", at progbits
.globl i
.align 4
i:
.long 7 # 0x7
.size i, 4
... is given ELF symbol type STT_TLS by gcc's assembler, but
STT_OBJECT by clang's assembler.
I think this used to work, a few weeks ago. Has anything changed in
this are recently?
Thanks,
Jay.