https://sourceware.org/bugzilla/show_bug.cgi?id=22832
--- Comment #4 from James Clarke <jrtc27 at jrtc27 dot com> --- So, after debugging this, the problem is as follows: Rust is using LLVM with -integrated-as (at least effectively; it may well be using it as a library and setting the flag itself, but the point is that the lowered IR is fed straight into the object code backend rather than being serialised via assembly and then assembled separately). LLVM's SparcMCCodeEmitter::getCallTargetOpValue handles __tls_get_addr specially to not emit an R_SPARC_WDISP30/WPLT30, and somewhere else the R_SPARC_TLS_LDM_CALL gets emitted, but the important point is that __tls_get_addr is never added to the output object file's symbol table despite being the symbolic operand to the call instruction. Thus, when linking one of these object files, that object file's hash table never pulls in the definition of __tls_get_addr, and so when _bfd_sparc_elf_check_relocs is called for an R_SPARC_TLS_LDM_CALL, it looks up __tls_get_addr, doesn't find it, and so an entry is created, since TRUE is passed to bfd_link_hash_lookup for create, but this entry has type bfd_link_hash_new, and this never changes. So it seems to me there are two issues here: 1. LLVM should be emitting an entry for __tls_get_addr in its symbol table so it is made visible to the object file. 2. ld should gracefully handle this case. If this case is an error, it should instead be passing FALSE for create to bfd_link_hash_lookup, and if the result is NULL, printing an error; otherwise, if this case should work, something needs to implicitly pull in the symbol (and in theory LLVM doesn't need to change, though in practice it's best to do so anyway for compatibility). I've talked specifically about local-dynamic here for simplicity, but global-dynamic has the same issue too. Note that gold also falls foul of this, giving "gold: internal error in tls_get_addr_sym, at ../../gold/sparc.cc:391", though line 391 is "gold_assert(this->tls_get_addr_sym_);" which is much easier to debug! Reproduction: jrtc27@deb4g:~/tmp/22832$ cat 22832.c __thread int x; int f(void) { return x; } jrtc27@deb4g:~/tmp/22832$ clang -integrated-as -o 22832.o -fPIC -c 22832.c jrtc27@deb4g:~/tmp/22832$ readelf -Wrs 22832.o Relocation section '.rela.text' at offset 0x138 contains 6 entries: Offset Info Type Symbol's Value Symbol's Name + Addend 0000000000000008 0000000300000011 R_SPARC_PC22 0000000000000000 _GLOBAL_OFFSET_TABLE_ + 4 000000000000000c 0000000300000010 R_SPARC_PC10 0000000000000000 _GLOBAL_OFFSET_TABLE_ + 8 0000000000000014 0000000500000038 R_SPARC_TLS_GD_HI22 0000000000000000 x + 0 0000000000000018 0000000500000039 R_SPARC_TLS_GD_LO10 0000000000000000 x + 0 000000000000001c 000000050000003a R_SPARC_TLS_GD_ADD 0000000000000000 x + 0 0000000000000020 000000050000003b R_SPARC_TLS_GD_CALL 0000000000000000 x + 0 Symbol table '.symtab' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS 22832.c 2: 0000000000000000 0 TLS LOCAL DEFAULT 4 .tbss 3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_ 4: 0000000000000000 52 FUNC GLOBAL DEFAULT 2 f 5: 0000000000000000 4 TLS GLOBAL DEFAULT 4 x jrtc27@deb4g:~/tmp/22832$ ld -o lib22832.so -shared 22832.o ld: BFD (GNU Binutils) 2.30.51.20180211 internal error, aborting at elflink.c:9710 in elf_link_output_extsym ld: Please report this bug. jrtc27@deb4g:~/tmp/22832$ gold -o lib22832.so -shared 22832.o gold: internal error in tls_get_addr_sym, at ../../gold/sparc.cc:391 -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils