[lld] r252979 - [elf2] Implement global dynamic tls.

Michael J. Spencer via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 12 16:28:35 PST 2015


Author: mspencer
Date: Thu Nov 12 18:28:34 2015
New Revision: 252979

URL: http://llvm.org/viewvc/llvm-project?rev=252979&view=rev
Log:
[elf2] Implement global dynamic tls.

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

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Nov 12 18:28:34 2015
@@ -126,6 +126,14 @@ void InputSectionBase<ELFT>::relocate(
     }
 
     SymbolBody &Body = *File->getSymbolBody(SymIndex)->repl();
+
+    if (Type == Target->getTlsGlobalDynamicReloc()) {
+      Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
+                          Out<ELFT>::Got->getEntryAddr(Body) +
+                              getAddend<ELFT>(RI));
+      continue;
+    }
+
     uintX_t SymVA = getSymVA<ELFT>(Body);
     if (Target->relocNeedsPlt(Type, Body)) {
       SymVA = Out<ELFT>::Plt->getEntryAddr(Body);

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Thu Nov 12 18:28:34 2015
@@ -80,6 +80,9 @@ GotSection<ELFT>::GotSection()
 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
   Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
   Entries.push_back(Sym);
+  // Global Dynamic TLS entries take two GOT slots.
+  if (Sym->isTLS())
+    Entries.push_back(nullptr);
 }
 
 template <class ELFT> uint32_t GotSection<ELFT>::addLocalModuleTlsIndex() {
@@ -187,8 +190,13 @@ template <class ELFT> void RelocationSec
     auto *P = reinterpret_cast<Elf_Rel *>(Buf);
     Buf += EntrySize;
 
-    InputSectionBase<ELFT> &C = Rel.C;
-    const Elf_Rel &RI = Rel.RI;
+    // Skip placeholder for global dynamic TLS relocation pair. It was already
+    // handled by the previous relocation.
+    if (!Rel.C || !Rel.RI)
+      continue;
+
+    InputSectionBase<ELFT> &C = *Rel.C;
+    const Elf_Rel &RI = *Rel.RI;
     uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
     const ObjectFile<ELFT> &File = *C.getFile();
     SymbolBody *Body = File.getSymbolBody(SymIndex);
@@ -205,6 +213,17 @@ template <class ELFT> void RelocationSec
       continue;
     }
 
+    if (Body && Type == Target->getTlsGlobalDynamicReloc()) {
+      P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
+                          Target->getTlsModuleIndexReloc(), Config->Mips64EL);
+      P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
+      auto *PNext = reinterpret_cast<Elf_Rel *>(Buf);
+      PNext->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
+                              Target->getTlsOffsetReloc(), Config->Mips64EL);
+      PNext->r_offset = Out<ELFT>::Got->getEntryAddr(*Body) + sizeof(uintX_t);
+      continue;
+    }
+
     bool NeedsCopy = Body && Target->relocNeedsCopy(Type, *Body);
     bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body);
     bool CanBePreempted = canBePreempted(Body, NeedsGot);

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Thu Nov 12 18:28:34 2015
@@ -170,8 +170,8 @@ private:
 
 template <class ELFT> struct DynamicReloc {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
-  InputSectionBase<ELFT> &C;
-  const Elf_Rel &RI;
+  InputSectionBase<ELFT> *C;
+  const Elf_Rel *RI;
 };
 
 template <class ELFT>

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Nov 12 18:28:34 2015
@@ -216,7 +216,9 @@ X86_64TargetInfo::X86_64TargetInfo() {
   PltReloc = R_X86_64_JUMP_SLOT;
   RelativeReloc = R_X86_64_RELATIVE;
   TlsLocalDynamicReloc = R_X86_64_TLSLD;
+  TlsGlobalDynamicReloc = R_X86_64_TLSGD;
   TlsModuleIndexReloc = R_X86_64_DTPMOD64;
+  TlsOffsetReloc = R_X86_64_DTPOFF64;
   LazyRelocations = true;
   PltEntrySize = 16;
   PltZeroEntrySize = 16;
@@ -335,6 +337,7 @@ void X86_64TargetInfo::relocateOne(uint8
   case R_X86_64_GOTPCREL:
   case R_X86_64_PLT32:
   case R_X86_64_TLSLD:
+  case R_X86_64_TLSGD:
     write32le(Loc, SA - P);
     break;
   case R_X86_64_64:

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Thu Nov 12 18:28:34 2015
@@ -30,7 +30,9 @@ public:
   unsigned getGotRefReloc() const { return GotRefReloc; }
   unsigned getRelativeReloc() const { return RelativeReloc; }
   unsigned getTlsLocalDynamicReloc() const { return TlsLocalDynamicReloc; }
+  unsigned getTlsGlobalDynamicReloc() const { return TlsGlobalDynamicReloc; }
   unsigned getTlsModuleIndexReloc() const { return TlsModuleIndexReloc; }
+  unsigned getTlsOffsetReloc() const { return TlsOffsetReloc; }
   unsigned getPltZeroEntrySize() const { return PltZeroEntrySize; }
   unsigned getPltEntrySize() const { return PltEntrySize; }
   bool supportsLazyRelocations() const { return LazyRelocations; }
@@ -70,7 +72,9 @@ protected:
   unsigned PltReloc;
   unsigned RelativeReloc;
   unsigned TlsLocalDynamicReloc = 0;
+  unsigned TlsGlobalDynamicReloc = 0;
   unsigned TlsModuleIndexReloc;
+  unsigned TlsOffsetReloc;
   unsigned PltEntrySize = 8;
   unsigned PltZeroEntrySize = 0;
   unsigned GotHeaderEntriesNum = 0;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Nov 12 18:28:34 2015
@@ -203,7 +203,7 @@ void Writer<ELFT>::scanRelocs(
       if (Out<ELFT>::LocalModuleTlsIndexOffset == uint32_t(-1)) {
         Out<ELFT>::LocalModuleTlsIndexOffset =
             Out<ELFT>::Got->addLocalModuleTlsIndex();
-        Out<ELFT>::RelaDyn->addReloc({C, RI});
+        Out<ELFT>::RelaDyn->addReloc({&C, &RI});
       }
       continue;
     }
@@ -215,6 +215,19 @@ void Writer<ELFT>::scanRelocs(
 
     if (Body)
       Body = Body->repl();
+
+    if (Body && Body->isTLS()) {
+      if (Type != Target->getTlsGlobalDynamicReloc())
+        continue;
+      if (Body->isInGot())
+        continue;
+      Out<ELFT>::Got->addEntry(Body);
+      Out<ELFT>::RelaDyn->addReloc({&C, &RI});
+      Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
+      Body->setUsedInDynamicReloc();
+      continue;
+    }
+
     bool NeedsGot = false;
     bool NeedsPlt = false;
     if (Body) {
@@ -257,9 +270,9 @@ void Writer<ELFT>::scanRelocs(
     if (CBP)
       Body->setUsedInDynamicReloc();
     if (NeedsPlt && Target->supportsLazyRelocations())
-      Out<ELFT>::RelaPlt->addReloc({C, RI});
+      Out<ELFT>::RelaPlt->addReloc({&C, &RI});
     else
-      Out<ELFT>::RelaDyn->addReloc({C, RI});
+      Out<ELFT>::RelaDyn->addReloc({&C, &RI});
   }
 }
 

Modified: lld/trunk/test/elf2/tls-dynamic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls-dynamic.s?rev=252979&r1=252978&r2=252979&view=diff
==============================================================================
--- lld/trunk/test/elf2/tls-dynamic.s (original)
+++ lld/trunk/test/elf2/tls-dynamic.s Thu Nov 12 18:28:34 2015
@@ -11,6 +11,10 @@
   leaq  a at dtpoff(%rax), %rcx
   leaq  b at dtpoff(%rax), %rcx
   .long	b at dtpoff, 0
+  leaq  c at tlsgd(%rip), %rdi
+  rex64
+  callq __tls_get_addr at PLT
+  leaq  c at dtpoff(%rax), %rcx
 
   .global	a
   .hidden a
@@ -23,8 +27,14 @@ a:
   .align 4
 b:
 	.long	0
+  
+  .global c
+  .section	.tbss,"awT", at nobits
+  .align 4
+c:
+	.long	0
 
-// Get the address of the got, and check that it has two entries.
+// Get the address of the got, and check that it has 4 entries.
 
 // CHECK:      Sections [
 // CHECK:          Name: .got
@@ -35,15 +45,18 @@ b:
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x20D0
 // CHECK-NEXT:     Offset:
-// CHECK-NEXT:     Size: 16
+// CHECK-NEXT:     Size: 32
 
 // 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:   }
 
 // 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.
 
 // DIS:      Disassembly of section .text:
 // DIS-NEXT: .text:
@@ -57,3 +70,6 @@ b:
 // DIS-NEXT:     1028: 00 00
 // DIS-NEXT:     102a: 00 00
 // DIS-NEXT:     102c: 00 00
+// DIS-NEXT:     102e: {{.+}} leaq    4267(%rip), %rdi
+// DIS-NEXT:     1035: {{.+}} callq
+// DIS-NEXT:     103b: {{.+}} leaq    8(%rax), %rcx




More information about the llvm-commits mailing list