[lld] r254090 - [ELF/x86] Implemented R_386_TLS_LE_32, R_386_TLS_LE relocations.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 25 12:41:54 PST 2015


Author: grimar
Date: Wed Nov 25 14:41:53 2015
New Revision: 254090

URL: http://llvm.org/viewvc/llvm-project?rev=254090&view=rev
Log:
[ELF/x86] Implemented R_386_TLS_LE_32, R_386_TLS_LE relocations.

This patch implements next relocations:
R_386_TLS_LE - Negative offset relative to static TLS (GNU version).
R_386_TLS_LE_32 - Offset relative to static TLS block.

These ones are created when using next code sequences:
* @tpoff - The operator must be used to compute an immediate value. The linker will report
an error if the referenced variable is not defined or it is not code for the executable
itself. No GOT entry is created in this case.
* @ntpoff Calculate the negative offset of the variable it is added to relative to the static TLS block.
The operator must be used to compute an immediate value. The linker will report
an error if the referenced variable is not defined or it is not code for the executable
itself. No GOT entry is created in this case.

Information was found in Ulrich Drepper, ELF Handling For Thread-Local Storage, http://www.akkadia.org/drepper/tls.pdf, (6.2, p76)

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

Added:
    lld/trunk/test/ELF/tls-i686.s
Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.cpp
    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=254090&r1=254089&r2=254090&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Nov 25 14:41:53 2015
@@ -151,6 +151,8 @@ void InputSectionBase<ELFT>::relocate(
     } else if (!Target->relocNeedsCopy(Type, Body) &&
                isa<SharedSymbol<ELFT>>(Body)) {
       continue;
+    } else if (Target->isTlsDynReloc(Type)) {
+      continue;
     }
     Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
                         SymVA + getAddend<ELFT>(RI));

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=254090&r1=254089&r2=254090&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Nov 25 14:41:53 2015
@@ -241,7 +241,8 @@ template <class ELFT> void RelocationSec
                             Config->Mips64EL);
       else
         P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
-                            NeedsCopy ? Target->getCopyReloc() : Type,
+                            NeedsCopy ? Target->getCopyReloc()
+                                      : Target->getDynReloc(Type),
                             Config->Mips64EL);
     } else {
       P->setSymbolAndType(0, Target->getRelativeReloc(), Config->Mips64EL);

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=254090&r1=254089&r2=254090&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Nov 25 14:41:53 2015
@@ -46,6 +46,8 @@ namespace {
 class X86TargetInfo final : public TargetInfo {
 public:
   X86TargetInfo();
+  unsigned getDynReloc(unsigned Type) const override;
+  bool isTlsDynReloc(unsigned Type) const override;
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
@@ -62,6 +64,7 @@ class X86_64TargetInfo final : public Ta
 public:
   X86_64TargetInfo();
   unsigned getPltRefReloc(unsigned Type) const override;
+  bool isTlsDynReloc(unsigned Type) const override;
   void writeGotPltHeaderEntries(uint8_t *Buf) const override;
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -182,6 +185,20 @@ X86TargetInfo::X86TargetInfo() {
   PltReloc = R_386_JUMP_SLOT;
 }
 
+unsigned X86TargetInfo::getDynReloc(unsigned Type) const {
+  if (Type == R_386_TLS_LE)
+    return R_386_TLS_TPOFF;
+  if (Type == R_386_TLS_LE_32)
+    return R_386_TLS_TPOFF32;
+  return Type;
+}
+
+bool X86TargetInfo::isTlsDynReloc(unsigned Type) const {
+  if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32)
+    return Config->Shared;
+  return false;
+}
+
 void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
 void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                                       uint64_t PltEntryAddr) const {}
@@ -225,6 +242,12 @@ void X86TargetInfo::relocateOne(uint8_t
   case R_386_32:
     add32le(Loc, SA);
     break;
+  case R_386_TLS_LE:
+    write32le(Loc, SA - Out<ELF32LE>::TlsPhdr->p_memsz);
+    break;
+  case R_386_TLS_LE_32:
+    write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - SA);
+    break;
   default:
     error("unrecognized reloc " + Twine(Type));
   }
@@ -242,7 +265,6 @@ X86_64TargetInfo::X86_64TargetInfo() {
   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;
@@ -300,6 +322,10 @@ bool X86_64TargetInfo::relocNeedsGot(uin
          relocNeedsPlt(Type, S);
 }
 
+bool X86_64TargetInfo::isTlsDynReloc(unsigned Type) const {
+  return Type == R_X86_64_GOTTPOFF;
+}
+
 unsigned X86_64TargetInfo::getPltRefReloc(unsigned Type) const {
   if (Type == R_X86_64_PLT32)
     return R_X86_64_PC32;

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=254090&r1=254089&r2=254090&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Wed Nov 25 14:41:53 2015
@@ -28,7 +28,6 @@ public:
   unsigned getPltReloc() const { return PltReloc; }
   unsigned getRelativeReloc() const { return RelativeReloc; }
   unsigned getTlsGotReloc() const { return TlsGotReloc; }
-  unsigned getTlsPcRelGotReloc() const { return TlsPcRelGotReloc; }
   bool isTlsLocalDynamicReloc(unsigned Type) const {
     return Type == TlsLocalDynamicReloc;
   }
@@ -42,6 +41,8 @@ public:
   bool supportsLazyRelocations() const { return LazyRelocations; }
   unsigned getGotHeaderEntriesNum() const { return GotHeaderEntriesNum; }
   unsigned getGotPltHeaderEntriesNum() const { return GotPltHeaderEntriesNum; }
+  virtual unsigned getDynReloc(unsigned Type) const { return Type; }
+  virtual bool isTlsDynReloc(unsigned Type) const { return false; }
   virtual unsigned getGotRefReloc(unsigned Type) const;
   virtual unsigned getPltRefReloc(unsigned Type) const;
   virtual void writeGotHeaderEntries(uint8_t *Buf) const;
@@ -84,7 +85,6 @@ protected:
   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=254090&r1=254089&r2=254090&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Nov 25 14:41:53 2015
@@ -229,7 +229,7 @@ void Writer<ELFT>::scanRelocs(
       continue;
     }
 
-    if ((Body && Body->isTLS()) && Type != Target->getTlsPcRelGotReloc())
+    if ((Body && Body->isTLS()) && !Target->isTlsDynReloc(Type))
       continue;
 
     bool NeedsGot = false;

Added: lld/trunk/test/ELF/tls-i686.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/tls-i686.s?rev=254090&view=auto
==============================================================================
--- lld/trunk/test/ELF/tls-i686.s (added)
+++ lld/trunk/test/ELF/tls-i686.s Wed Nov 25 14:41:53 2015
@@ -0,0 +1,69 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t
+// RUN: ld.lld %t -o %tout
+// RUN: ld.lld %t -shared -o %tsharedout
+// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
+// RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
+// RUN: llvm-objdump -d %tsharedout | FileCheck %s --check-prefix=DISSHARED
+// RUN: llvm-readobj -r %tsharedout | FileCheck %s --check-prefix=RELOCSHARED
+
+.section ".tdata", "awT", @progbits
+.globl var
+.globl var1
+var:
+.long 0
+var1:
+.long 1
+
+.text
+.global _start
+_start:
+ movl $var at tpoff, %edx
+ movl %gs:0, %ecx
+ subl %edx, %eax
+ movl $var1 at tpoff, %edx
+ movl %gs:0, %ecx
+ subl %edx, %eax
+
+ movl %gs:0, %ecx
+ leal var at ntpoff(%ecx), %eax
+ movl %gs:0, %ecx
+ leal var1 at ntpoff(%ecx), %eax
+
+// DIS:      Disassembly of section .text:
+// DIS-NEXT: _start:
+// DIS-NEXT: 11000: ba 08 00 00 00       movl $8, %edx
+// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 1100c: 29 d0                subl %edx, %eax
+// DIS-NEXT: 1100e: ba 04 00 00 00       movl $4, %edx
+// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 1101a: 29 d0                subl %edx, %eax
+// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 11023: 8d 81 f8 ff ff ff    leal -8(%ecx), %eax
+// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 11030: 8d 81 fc ff ff ff    leal -4(%ecx), %eax
+
+// RELOC: Relocations [
+// RELOC-NEXT: ]
+
+// DISSHARED: Disassembly of section .text:
+// DISSHARED-NEXT: _start:
+// DISSHARED-NEXT: 1000: ba 00 00 00 00 movl   $0, %edx
+// DISSHARED-NEXT: 1005: 65 8b 0d 00 00 00 00  movl %gs:0, %ecx
+// DISSHARED-NEXT: 100c: 29 d0 subl            %edx, %eax
+// DISSHARED-NEXT: 100e: ba 00 00 00 00        movl $0, %edx
+// DISSHARED-NEXT: 1013: 65 8b 0d 00 00 00 00  movl %gs:0, %ecx
+// DISSHARED-NEXT: 101a: 29 d0 subl            %edx, %eax
+// DISSHARED-NEXT: 101c: 65 8b 0d 00 00 00 00  movl %gs:0, %ecx
+// DISSHARED-NEXT: 1023: 8d 81 00 00 00 00     leal (%ecx), %eax
+// DISSHARED-NEXT: 1029: 65 8b 0d 00 00 00 00  movl %gs:0, %ecx
+// DISSHARED-NEXT: 1030: 8d 81 00 00 00 00     leal (%ecx), %eax
+
+// RELOCSHARED:      Relocations [
+// RELOCSHARED-NEXT: Section (4) .rel.dyn {
+// RELOCSHARED-NEXT:   0x1001 R_386_TLS_TPOFF32 var 0x0
+// RELOCSHARED-NEXT:   0x100F R_386_TLS_TPOFF32 var1 0x0
+// RELOCSHARED-NEXT:   0x1025 R_386_TLS_TPOFF var 0x0
+// RELOCSHARED-NEXT:   0x1032 R_386_TLS_TPOFF var1 0x0
+// RELOCSHARED-NEXT:  }
+// RELOCSHARED-NEXT: ]




More information about the llvm-commits mailing list