[lld] r253049 - [ELF2] - Implemented R_X86_64_GOTTPOFF relocation

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 08:28:53 PST 2015


Author: grimar
Date: Fri Nov 13 10:28:53 2015
New Revision: 253049

URL: http://llvm.org/viewvc/llvm-project?rev=253049&view=rev
Log:
[ELF2] - Implemented R_X86_64_GOTTPOFF relocation

Generates single GOT entry, R_X86_64_TPOFF64 is added to RelaDyn.

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

Added:
    lld/trunk/test/elf2/Inputs/tls-got.s
    lld/trunk/test/elf2/tls-got.s
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

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Nov 13 10:28:53 2015
@@ -140,7 +140,7 @@ void InputSectionBase<ELFT>::relocate(
       Type = Target->getPLTRefReloc(Type);
     } else if (Target->relocNeedsGot(Type, Body)) {
       SymVA = Out<ELFT>::Got->getEntryAddr(Body);
-      Type = Target->getGotRefReloc();
+      Type = Body.isTLS() ? Target->getTlsGotReloc() : Target->getGotRefReloc();
     } else if (Target->relocPointsToGot(Type)) {
       SymVA = Out<ELFT>::Got->getVA();
       Type = Target->getPCRelReloc();

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Nov 13 10:28:53 2015
@@ -80,9 +80,13 @@ GotSection<ELFT>::GotSection()
 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
   Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
   Entries.push_back(Sym);
+}
+
+template <class ELFT> void GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
+  Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
   // Global Dynamic TLS entries take two GOT slots.
-  if (Sym->isTLS())
-    Entries.push_back(nullptr);
+  Entries.push_back(Sym);
+  Entries.push_back(nullptr);
 }
 
 template <class ELFT> uint32_t GotSection<ELFT>::addLocalModuleTlsIndex() {
@@ -231,10 +235,11 @@ template <class ELFT> void RelocationSec
                      Target->relocNeedsPlt(Type, *Body);
 
     if (CanBePreempted) {
+      unsigned GotReloc =
+          Body->isTLS() ? Target->getTlsGotReloc() : Target->getGotReloc();
       if (NeedsGot)
         P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
-                            LazyReloc ? Target->getPltReloc()
-                                      : Target->getGotReloc(),
+                            LazyReloc ? Target->getPltReloc() : GotReloc,
                             Config->Mips64EL);
       else
         P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Nov 13 10:28:53 2015
@@ -118,6 +118,7 @@ public:
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
+  void addDynTlsEntry(SymbolBody *Sym);
   uint32_t addLocalModuleTlsIndex();
   bool empty() const { return Entries.empty(); }
   uintX_t getEntryAddr(const SymbolBody &B) const;

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Nov 13 10:28:53 2015
@@ -215,10 +215,12 @@ X86_64TargetInfo::X86_64TargetInfo() {
   GotRefReloc = R_X86_64_PC32;
   PltReloc = R_X86_64_JUMP_SLOT;
   RelativeReloc = R_X86_64_RELATIVE;
+  TlsGotReloc = R_X86_64_TPOFF64;
   TlsLocalDynamicReloc = R_X86_64_TLSLD;
   TlsGlobalDynamicReloc = R_X86_64_TLSGD;
   TlsModuleIndexReloc = R_X86_64_DTPMOD64;
   TlsOffsetReloc = R_X86_64_DTPOFF64;
+  TlsPcRelGotReloc = R_X86_64_GOTTPOFF;
   LazyRelocations = true;
   PltEntrySize = 16;
   PltZeroEntrySize = 16;
@@ -266,7 +268,8 @@ bool X86_64TargetInfo::relocNeedsCopy(ui
 }
 
 bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
-  return Type == R_X86_64_GOTPCREL || relocNeedsPlt(Type, S);
+  return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_GOTPCREL ||
+         relocNeedsPlt(Type, S);
 }
 
 unsigned X86_64TargetInfo::getPLTRefReloc(unsigned Type) const {
@@ -338,6 +341,7 @@ void X86_64TargetInfo::relocateOne(uint8
   case R_X86_64_PLT32:
   case R_X86_64_TLSLD:
   case R_X86_64_TLSGD:
+  case R_X86_64_TPOFF64:
     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=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Nov 13 10:28:53 2015
@@ -29,6 +29,8 @@ public:
   unsigned getPltReloc() const { return PltReloc; }
   unsigned getGotRefReloc() const { return GotRefReloc; }
   unsigned getRelativeReloc() const { return RelativeReloc; }
+  unsigned getTlsGotReloc() const { return TlsGotReloc; }
+  unsigned getTlsPcRelGotReloc() const { return TlsPcRelGotReloc; }
   bool isTlsLocalDynamicReloc(unsigned Type) const {
     return Type == TlsLocalDynamicReloc;
   }
@@ -75,10 +77,12 @@ protected:
   unsigned GotReloc;
   unsigned PltReloc;
   unsigned RelativeReloc;
+  unsigned TlsGotReloc = 0;
   unsigned TlsLocalDynamicReloc = 0;
   unsigned TlsGlobalDynamicReloc = 0;
   unsigned TlsModuleIndexReloc;
   unsigned TlsOffsetReloc;
+  unsigned TlsPcRelGotReloc = 0;
   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=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Nov 13 10:28:53 2015
@@ -216,18 +216,19 @@ void Writer<ELFT>::scanRelocs(
     if (Body)
       Body = Body->repl();
 
-    if (Body && Body->isTLS()) {
-      if (!Target->isTlsGlobalDynamicReloc(Type))
-        continue;
+    if (Body && Body->isTLS() && Target->isTlsGlobalDynamicReloc(Type)) {
       if (Body->isInGot())
         continue;
-      Out<ELFT>::Got->addEntry(Body);
+      Out<ELFT>::Got->addDynTlsEntry(Body);
       Out<ELFT>::RelaDyn->addReloc({&C, &RI});
       Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
       Body->setUsedInDynamicReloc();
       continue;
     }
 
+    if ((Body && Body->isTLS()) && Type != Target->getTlsPcRelGotReloc())
+      continue;
+
     bool NeedsGot = false;
     bool NeedsPlt = false;
     if (Body) {

Added: lld/trunk/test/elf2/Inputs/tls-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/tls-got.s?rev=253049&view=auto
==============================================================================
--- lld/trunk/test/elf2/Inputs/tls-got.s (added)
+++ lld/trunk/test/elf2/Inputs/tls-got.s Fri Nov 13 10:28:53 2015
@@ -0,0 +1,14 @@
+.type tls0, at object
+.section .tbss,"awT", at nobits
+.globl tls0
+.align 4
+tls0:
+ .long 0
+ .size tls0, 4
+
+.type  tls1, at object
+.globl tls1
+.align 4
+tls1:
+ .long 0
+ .size tls1, 4

Added: lld/trunk/test/elf2/tls-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls-got.s?rev=253049&view=auto
==============================================================================
--- lld/trunk/test/elf2/tls-got.s (added)
+++ lld/trunk/test/elf2/tls-got.s Fri Nov 13 10:28:53 2015
@@ -0,0 +1,58 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o
+// RUN: ld.lld2 -shared %t2.o -o %t2.so
+// RUN: ld.lld2 -e main %t1.o %t2.so -o %t3
+// RUN: llvm-readobj -s -r %t3 | FileCheck %s
+// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s
+
+// CHECK:      Section {
+// CHECK:      Index: 8
+// CHECK-NEXT: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[ADDR:.*]]
+// CHECK-NEXT: Offset: 0x20A0
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: }
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section (4) .rela.dyn {
+// CHECK-NEXT:     [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
+// CHECK-NEXT:     0x120A8 R_X86_64_TPOFF64 tls0 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+//0x11000 + 4249 + 7 = 0x120A0
+//0x1100A + 4247 + 7 = 0x120A8
+//0x11014 + 4237 + 7 = 0x120A8
+//DISASM:      Disassembly of section .text:
+//DISASM-NEXT: main:
+//DISASM-NEXT: 11000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax
+//DISASM-NEXT: 11007: 64 8b 00 movl %fs:(%rax), %eax
+//DISASM-NEXT: 1100a: 48 8b 05 97 10 00 00 movq 4247(%rip), %rax
+//DISASM-NEXT: 11011: 64 8b 00 movl %fs:(%rax), %eax
+//DISASM-NEXT: 11014: 48 8b 05 8d 10 00 00 movq 4237(%rip), %rax
+//DISASM-NEXT: 1101b: 64 8b 00 movl %fs:(%rax), %eax
+//DISASM-NEXT: 1101e: c3 retq
+
+.section .tdata,"awT", at progbits
+
+.text
+ .globl main
+ .align 16, 0x90
+ .type main, at function
+main:
+ movq tls1 at GOTTPOFF(%rip), %rax
+ movl %fs:0(%rax), %eax
+ movq tls0 at GOTTPOFF(%rip), %rax
+ movl %fs:0(%rax), %eax
+ movq tls0 at GOTTPOFF(%rip), %rax
+ movl %fs:0(%rax), %eax
+ ret




More information about the llvm-commits mailing list