[lld] r254443 - [ELF] - Fixed bug leading to miss of tls relocation when @tlsgd and @gottpoff relocations were used at the same time.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 1 11:20:28 PST 2015


Author: grimar
Date: Tue Dec  1 13:20:26 2015
New Revision: 254443

URL: http://llvm.org/viewvc/llvm-project?rev=254443&view=rev
Log:
[ELF] - Fixed bug leading to miss of tls relocation when @tlsgd and @gottpoff relocations were used at the same time.

Combination of @tlsgd and @gottpoff at the same time leads to miss of R_X86_64_TPOFF64 dynamic relocation. Patch fixes that.

@tlsgd(%rip) - Allocate two contiguous entries in the GOT to hold a tls index
structure (for passing to tls get addr).
@gottpoff(%rip) - Allocate one GOT entry to hold a variable offset in initial TLS
block (relative to TLS block end, %fs:0).

The same situation can be observed for x86 (probably others too, not sure) with corresponding for that target relocations: @tlsgd, @gotntpoff.

Differential revision: http://reviews.llvm.org/D15105

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/tls-dynamic.s

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=254443&r1=254442&r2=254443&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Dec  1 13:20:26 2015
@@ -132,7 +132,7 @@ void InputSectionBase<ELFT>::relocate(
     if (Target->isTlsGlobalDynamicReloc(Type) &&
         !Target->isTlsOptimized(Type, &Body)) {
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
-                          Out<ELFT>::Got->getEntryAddr(Body) +
+                          Out<ELFT>::Got->getGlobalDynAddr(Body) +
                               getAddend<ELFT>(RI));
       continue;
     }

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=254443&r1=254442&r2=254443&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Dec  1 13:20:26 2015
@@ -80,11 +80,14 @@ template <class ELFT> void GotSection<EL
   Entries.push_back(Sym);
 }
 
-template <class ELFT> void GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
-  Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
+template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
+  if (Sym->hasGlobalDynIndex())
+    return false;
+  Sym->GlobalDynIndex = Target->getGotHeaderEntriesNum() + Entries.size();
   // Global Dynamic TLS entries take two GOT slots.
   Entries.push_back(Sym);
   Entries.push_back(nullptr);
+  return true;
 }
 
 template <class ELFT> bool GotSection<ELFT>::addLocalModelTlsIndex() {
@@ -103,6 +106,12 @@ GotSection<ELFT>::getEntryAddr(const Sym
 }
 
 template <class ELFT>
+typename GotSection<ELFT>::uintX_t
+GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const {
+  return this->getVA() + B.GlobalDynIndex * sizeof(uintX_t);
+}
+
+template <class ELFT>
 const SymbolBody *GotSection<ELFT>::getMipsFirstGlobalEntry() const {
   return Entries.empty() ? nullptr : Entries.front();
 }
@@ -211,10 +220,10 @@ bool RelocationSection<ELFT>::applyTlsDy
   if (Body && Target->isTlsGlobalDynamicReloc(Type)) {
     P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
                         Target->getTlsModuleIndexReloc(), Config->Mips64EL);
-    P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
+    P->r_offset = Out<ELFT>::Got->getGlobalDynAddr(*Body);
     N->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
                         Target->getTlsOffsetReloc(), Config->Mips64EL);
-    N->r_offset = Out<ELFT>::Got->getEntryAddr(*Body) + sizeof(uintX_t);
+    N->r_offset = Out<ELFT>::Got->getGlobalDynAddr(*Body) + sizeof(uintX_t);
     return true;
   }
   return false;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=254443&r1=254442&r2=254443&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Dec  1 13:20:26 2015
@@ -118,10 +118,11 @@ public:
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
-  void addDynTlsEntry(SymbolBody *Sym);
+  bool addDynTlsEntry(SymbolBody *Sym);
   bool addLocalModelTlsIndex();
   bool empty() const { return Entries.empty(); }
   uintX_t getEntryAddr(const SymbolBody &B) const;
+  uintX_t getGlobalDynAddr(const SymbolBody &B) const;
 
   // Returns the symbol which corresponds to the first entry of the global part
   // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=254443&r1=254442&r2=254443&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Dec  1 13:20:26 2015
@@ -90,9 +90,11 @@ public:
   }
   void setDynamicSymbolTableIndex(unsigned V) { DynamicSymbolTableIndex = V; }
 
+  uint32_t GlobalDynIndex = -1;
   uint32_t GotIndex = -1;
   uint32_t GotPltIndex = -1;
   uint32_t PltIndex = -1;
+  bool hasGlobalDynIndex() { return GlobalDynIndex != uint32_t(-1); }
   bool isInGot() const { return GotIndex != -1U; }
   bool isInGotPlt() const { return GotPltIndex != -1U; }
   bool isInPlt() const { return PltIndex != -1U; }

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=254443&r1=254442&r2=254443&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Dec  1 13:20:26 2015
@@ -221,12 +221,11 @@ void Writer<ELFT>::scanRelocs(
     if (Body && Body->isTLS() && Target->isTlsGlobalDynamicReloc(Type)) {
       if (Target->isTlsOptimized(Type, Body))
         continue;
-      if (Body->isInGot())
-        continue;
-      Out<ELFT>::Got->addDynTlsEntry(Body);
-      Out<ELFT>::RelaDyn->addReloc({&C, &RI});
-      Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
-      Body->setUsedInDynamicReloc();
+      if (Out<ELFT>::Got->addDynTlsEntry(Body)) {
+        Out<ELFT>::RelaDyn->addReloc({&C, &RI});
+        Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
+        Body->setUsedInDynamicReloc();
+      }
       continue;
     }
 

Modified: lld/trunk/test/ELF/tls-dynamic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/tls-dynamic.s?rev=254443&r1=254442&r2=254443&view=diff
==============================================================================
--- lld/trunk/test/ELF/tls-dynamic.s (original)
+++ lld/trunk/test/ELF/tls-dynamic.s Tue Dec  1 13:20:26 2015
@@ -15,6 +15,9 @@
   rex64
   callq __tls_get_addr at PLT
   leaq  c at dtpoff(%rax), %rcx
+  // Initial Exec Model Code Sequence, II
+  movq c at gottpoff(%rip),%rax
+  movq %fs:(%rax),%rax
 
   .global a
   .hidden a
@@ -44,18 +47,20 @@ c:
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x20D0
 // CHECK-NEXT:     Offset:
-// CHECK-NEXT:     Size: 32
+// CHECK-NEXT:     Size: 40
 
 // CHECK:      Relocations [
 // CHECK:        Section ({{.+}}) .rela.dyn {
 // CHECK-NEXT:     0x20D0 R_X86_64_DTPMOD64 - 0x0
 // CHECK-NEXT:     0x20E0 R_X86_64_DTPMOD64 c 0x0
 // CHECK-NEXT:     0x20E8 R_X86_64_DTPOFF64 c 0x0
+// CHECK-NEXT:     0x20F0 R_X86_64_TPOFF64 c 0x0
 // CHECK-NEXT:   }
 
 // 4297 = (0x20D0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
 // 4285 = (0x20D0 + -4) - (0x100c + 3) // PC relative offset to got entry.
 // 4267 = (0x20E0 + -4) - (0x102e + 3) // PC relative offset to got entry.
+// 4263 = (0x20F0 + -4) - (0x1042 + 3) // PC relative offset to got entry.
 
 // DIS:      Disassembly of section .text:
 // DIS-NEXT: .text:
@@ -72,3 +77,5 @@ c:
 // DIS-NEXT:     102e: {{.+}} leaq    4267(%rip), %rdi
 // DIS-NEXT:     1035: {{.+}} callq
 // DIS-NEXT:     103b: {{.+}} leaq    8(%rax), %rcx
+// DIS-NEXT:     1042: {{.+}} movq    4263(%rip), %rax
+// DIS-NEXT:     1049: {{.+}} movq    %fs:(%rax), %rax




More information about the llvm-commits mailing list