Index: lld/trunk/ELF/SymbolTable.h =================================================================== --- lld/trunk/ELF/SymbolTable.h +++ lld/trunk/ELF/SymbolTable.h @@ -80,7 +80,8 @@ template void init(uint16_t EMachine); template void resolve(SymbolBody *Body); template - void reportConflict(const SymbolBody &Old, const SymbolBody &New); + void reportConflict(const Twine &Message, const SymbolBody &Old, + const SymbolBody &New, bool Warning); std::vector> ArchiveFiles; Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -175,7 +175,8 @@ } template -void SymbolTable::reportConflict(const SymbolBody &Old, const SymbolBody &New) { +void SymbolTable::reportConflict(const Twine &Message, const SymbolBody &Old, + const SymbolBody &New, bool Warning) { typedef typename ELFFile::Elf_Sym Elf_Sym; typedef typename ELFFile::Elf_Sym_Range Elf_Sym_Range; @@ -193,10 +194,10 @@ NewFile = F.get(); } - std::string Msg = (Twine("duplicate symbol: ") + Old.getName() + " in " + + std::string Msg = (Message + ": " + Old.getName() + " in " + OldFile->getName() + " and " + NewFile->getName()) .str(); - if (Config->AllowMultipleDefinition) + if (Warning) warning(Msg); else error(Msg); @@ -229,13 +230,18 @@ return; } + if (New->isTLS() != Existing->isTLS()) + reportConflict("TLS attribute mismatch for symbol", *Existing, *New, + false); + // compare() returns -1, 0, or 1 if the lhs symbol is less preferable, // equivalent (conflicting), or more preferable, respectively. int comp = Existing->compare(New); if (comp < 0) Sym->Body = New; else if (comp == 0) - reportConflict(*Existing, *New); + reportConflict("duplicate symbol", *Existing, *New, + Config->AllowMultipleDefinition); } Symbol *SymbolTable::insert(SymbolBody *New) { Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -63,6 +63,7 @@ bool isUsedInRegularObj() const { return IsUsedInRegularObj; } bool isUsedInDynamicReloc() const { return IsUsedInDynamicReloc; } void setUsedInDynamicReloc() { IsUsedInDynamicReloc = true; } + bool isTLS() const { return IsTLS; } // Returns the symbol name. StringRef getName() const { return Name; } @@ -96,9 +97,10 @@ template int compare(SymbolBody *Other); protected: - SymbolBody(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility) + SymbolBody(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, + bool IsTLS) : SymbolKind(K), IsWeak(IsWeak), MostConstrainingVisibility(Visibility), - Name(Name) { + IsTLS(IsTLS), Name(Name) { IsUsedInRegularObj = K != SharedKind && K != LazyKind; IsUsedInDynamicReloc = 0; } @@ -108,6 +110,7 @@ unsigned MostConstrainingVisibility : 2; unsigned IsUsedInRegularObj : 1; unsigned IsUsedInDynamicReloc : 1; + unsigned IsTLS : 1; unsigned DynamicSymbolTableIndex = 0; StringRef Name; Symbol *Backref = nullptr; @@ -125,7 +128,7 @@ typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; ELFSymbolBody(Kind K, StringRef Name, const Elf_Sym &Sym) : SymbolBody(K, Name, Sym.getBinding() == llvm::ELF::STB_WEAK, - Sym.getVisibility()), + Sym.getVisibility(), Sym.getType() == llvm::ELF::STT_TLS), Sym(Sym) {} public: @@ -272,7 +275,7 @@ class Lazy : public SymbolBody { public: Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S) - : SymbolBody(LazyKind, S.getName(), false, llvm::ELF::STV_DEFAULT), + : SymbolBody(LazyKind, S.getName(), false, llvm::ELF::STV_DEFAULT, false), File(F), Sym(S) {} static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; } Index: lld/trunk/test/elf2/Inputs/tls-mismatch.s =================================================================== --- lld/trunk/test/elf2/Inputs/tls-mismatch.s +++ lld/trunk/test/elf2/Inputs/tls-mismatch.s @@ -0,0 +1,4 @@ +.tbss +.globl tlsvar +tlsvar: + .space 4 Index: lld/trunk/test/elf2/tls-mismatch.s =================================================================== --- lld/trunk/test/elf2/tls-mismatch.s +++ lld/trunk/test/elf2/tls-mismatch.s @@ -0,0 +1,9 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2 +// RUN: not ld.lld2 %t %t2 -o %t3 2>&1 | FileCheck %s +// CHECK: TLS attribute mismatch for symbol: tlsvar + +.globl _start,tlsvar +_start: + movl tlsvar,%edx