[lld] r249817 - [ELF2] Check for TLS mismatch in symbol resolution.
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 9 02:58:41 PDT 2015
Author: ikudrin
Date: Fri Oct 9 04:58:39 2015
New Revision: 249817
URL: http://llvm.org/viewvc/llvm-project?rev=249817&view=rev
Log:
[ELF2] Check for TLS mismatch in symbol resolution.
The linker should generate an error if a TLS symbol is resolved
for a non-TLS reference and vice versa.
The patch addresses PR24244 (https://llvm.org/bugs/show_bug.cgi?id=24244)
Differential Revision: http://reviews.llvm.org/D13550
Added:
lld/trunk/test/elf2/Inputs/tls-mismatch.s
lld/trunk/test/elf2/tls-mismatch.s
Modified:
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Symbols.h
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=249817&r1=249816&r2=249817&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Oct 9 04:58:39 2015
@@ -175,7 +175,8 @@ void SymbolTable::addELFFile(ELFFileBase
}
template <class ELFT>
-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<ELFT>::Elf_Sym Elf_Sym;
typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
@@ -193,10 +194,10 @@ void SymbolTable::reportConflict(const S
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 @@ template <class ELFT> void SymbolTable::
return;
}
+ if (New->isTLS() != Existing->isTLS())
+ reportConflict<ELFT>("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<ELFT>(New);
if (comp < 0)
Sym->Body = New;
else if (comp == 0)
- reportConflict<ELFT>(*Existing, *New);
+ reportConflict<ELFT>("duplicate symbol", *Existing, *New,
+ Config->AllowMultipleDefinition);
}
Symbol *SymbolTable::insert(SymbolBody *New) {
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=249817&r1=249816&r2=249817&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Fri Oct 9 04:58:39 2015
@@ -80,7 +80,8 @@ private:
template <class ELFT> void init(uint16_t EMachine);
template <class ELFT> void resolve(SymbolBody *Body);
template <class ELFT>
- void reportConflict(const SymbolBody &Old, const SymbolBody &New);
+ void reportConflict(const Twine &Message, const SymbolBody &Old,
+ const SymbolBody &New, bool Warning);
std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=249817&r1=249816&r2=249817&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Oct 9 04:58:39 2015
@@ -63,6 +63,7 @@ public:
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 @@ public:
template <class ELFT> 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 @@ protected:
unsigned MostConstrainingVisibility : 2;
unsigned IsUsedInRegularObj : 1;
unsigned IsUsedInDynamicReloc : 1;
+ unsigned IsTLS : 1;
unsigned DynamicSymbolTableIndex = 0;
StringRef Name;
Symbol *Backref = nullptr;
@@ -125,7 +128,7 @@ protected:
typedef typename llvm::object::ELFFile<ELFT>::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 @@ public:
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; }
Added: lld/trunk/test/elf2/Inputs/tls-mismatch.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/tls-mismatch.s?rev=249817&view=auto
==============================================================================
--- lld/trunk/test/elf2/Inputs/tls-mismatch.s (added)
+++ lld/trunk/test/elf2/Inputs/tls-mismatch.s Fri Oct 9 04:58:39 2015
@@ -0,0 +1,4 @@
+.tbss
+.globl tlsvar
+tlsvar:
+ .space 4
Added: lld/trunk/test/elf2/tls-mismatch.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls-mismatch.s?rev=249817&view=auto
==============================================================================
--- lld/trunk/test/elf2/tls-mismatch.s (added)
+++ lld/trunk/test/elf2/tls-mismatch.s Fri Oct 9 04:58:39 2015
@@ -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
More information about the llvm-commits
mailing list