[lld] r174425 - [ELF] Replace local dynamic tls access with direct access.

Michael J. Spencer bigcheesegs at gmail.com
Tue Feb 5 11:14:07 PST 2013


Author: mspencer
Date: Tue Feb  5 13:14:07 2013
New Revision: 174425

URL: http://llvm.org/viewvc/llvm-project?rev=174425&view=rev
Log:
[ELF] Replace local dynamic tls access with direct access.

Modified:
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
    lld/trunk/test/elf/Inputs/tls.S
    lld/trunk/test/elf/Inputs/tls.x86-64
    lld/trunk/test/elf/tls.test

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=174425&r1=174424&r2=174425&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Tue Feb  5 13:14:07 2013
@@ -61,6 +61,8 @@ ErrorOr<void> X86_64TargetRelocationHand
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
 
   switch (ref.kind()) {
+  case R_X86_64_NONE:
+    break;
   case R_X86_64_64:
     reloc64(location, relocVAddress, targetVAddress, ref.addend());
     break;
@@ -74,6 +76,7 @@ ErrorOr<void> X86_64TargetRelocationHand
     reloc32S(location, relocVAddress, targetVAddress, ref.addend());
     break;
   case R_X86_64_TPOFF64:
+  case R_X86_64_DTPOFF32:
   case R_X86_64_TPOFF32: {
     // Get the start and end of the TLS segment.
     if (_tlsSize == 0) {
@@ -88,7 +91,7 @@ ErrorOr<void> X86_64TargetRelocationHand
       if (tbss)
         _tlsSize += tbss->memSize();
     }
-    if (ref.kind() == R_X86_64_TPOFF32) {
+    if (ref.kind() == R_X86_64_TPOFF32 || ref.kind() == R_X86_64_DTPOFF32) {
       int32_t result = (int32_t)(targetVAddress - _tlsSize);
       *reinterpret_cast<llvm::support::little32_t *>(location) = result;
     } else {
@@ -96,6 +99,13 @@ ErrorOr<void> X86_64TargetRelocationHand
       *reinterpret_cast<llvm::support::little64_t *>(location) = result;
     }
     break;
+  case R_X86_64_TLSLD:
+    // Rewrite to move %fs:0 into %rax. Technically we should verify that the
+    // next relocation is a PC32 to __tls_get_addr...
+    static uint8_t instr[] = { 0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25,
+                               0x00, 0x00, 0x00, 0x00 };
+    std::memcpy(location - 3, instr, sizeof(instr));
+    break;
   }
   // Runtime only relocations. Ignore here.
   case R_X86_64_IRELATIVE:
@@ -143,9 +153,35 @@ public:
     return ArrayRef<uint8_t>();
   }
 };
+
+class TLSGETADDRAtom : public SimpleDefinedAtom {
+public:
+  TLSGETADDRAtom(const File &f) : SimpleDefinedAtom(f) {}
+
+  virtual StringRef name() const { return "__tls_get_addr"; }
+
+  virtual Scope scope() const { return scopeGlobal; }
+
+  virtual Merge merge() const { return mergeAsWeak; }
+
+  virtual SectionChoice sectionChoice() const { return sectionCustomRequired; }
+
+  virtual StringRef customSectionName() const { return ".text"; }
+
+  virtual ContentType contentType() const { return typeCode; }
+
+  virtual uint64_t size() const { return 0; }
+
+  virtual ContentPermissions permissions() const { return permR_X; }
+
+  virtual Alignment alignment() const { return Alignment(0); }
+
+  virtual ArrayRef<uint8_t> rawContent() const { return ArrayRef<uint8_t>(); }
+};
 } // end anon namespace
 
 void X86_64TargetHandler::addFiles(InputFiles &f) {
   _gotFile.addAtom(*new (_gotFile._alloc) GLOBAL_OFFSET_TABLEAtom(_gotFile));
+  _gotFile.addAtom(*new (_gotFile._alloc) TLSGETADDRAtom(_gotFile));
   f.appendFile(_gotFile);
 }

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp?rev=174425&r1=174424&r2=174425&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp Tue Feb  5 13:14:07 2013
@@ -137,8 +137,12 @@ class GOTPLTPass LLVM_FINAL : public Pas
     const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target());
     switch (ref.kind()) {
     case R_X86_64_PLT32:
-      // Static code doesn't need PLTs.
-      const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
+      // __tls_get_addr is handled elsewhere.
+      if (ref.target() && ref.target()->name() == "__tls_get_addr")
+        const_cast<Reference &>(ref).setKind(R_X86_64_NONE);
+      else
+        // Static code doesn't need PLTs.
+        const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
       break;
     case R_X86_64_PC32: // IFUNC
       if (da && da->contentType() == DefinedAtom::typeResolver)

Modified: lld/trunk/test/elf/Inputs/tls.S
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/tls.S?rev=174425&r1=174424&r2=174425&view=diff
==============================================================================
--- lld/trunk/test/elf/Inputs/tls.S (original)
+++ lld/trunk/test/elf/Inputs/tls.S Tue Feb  5 13:14:07 2013
@@ -17,6 +17,15 @@ GOTTPOFF:
         movl %fs:0(%rax), %eax
         ret
 
+        .text
+        .globl TLSLD
+        .type  TLSLD, at function
+TLSLD:
+        leaq tls0 at tlsld(%rip), %rdi
+        call __tls_get_addr at plt
+        leaq tls0 at dtpoff(%rax), %rax
+        ret
+
         .type   tls0, at object            # @tls0
         .section        .tbss,"awT", at nobits
         .globl  tls0

Modified: lld/trunk/test/elf/Inputs/tls.x86-64
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/tls.x86-64?rev=174425&r1=174424&r2=174425&view=diff
==============================================================================
Binary files lld/trunk/test/elf/Inputs/tls.x86-64 (original) and lld/trunk/test/elf/Inputs/tls.x86-64 Tue Feb  5 13:14:07 2013 differ

Modified: lld/trunk/test/elf/tls.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/tls.test?rev=174425&r1=174424&r2=174425&view=diff
==============================================================================
--- lld/trunk/test/elf/tls.test (original)
+++ lld/trunk/test/elf/tls.test Tue Feb  5 13:14:07 2013
@@ -26,8 +26,14 @@ YAML: type: got
 YAML: kind: R_X86_64_TPOFF64
 YAML: target: tls2
 
+// main
 CHECK: addl %fs:-4
 CHECK: addl %fs:-8
 CHECK: addl %fs:-12
 
+// GOTTPOFF
 CHECK: movq {{[0-9]+}}(%rip)
+
+// TLSLD
+CHECK: movq %fs:0, %rax
+CHECK: leaq -8(%rax), %rax





More information about the llvm-commits mailing list