[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