[lld] r252352 - Round up the memsize of PT_TLS.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 6 14:14:44 PST 2015


Author: rafael
Date: Fri Nov  6 16:14:44 2015
New Revision: 252352

URL: http://llvm.org/viewvc/llvm-project?rev=252352&view=rev
Log:
Round up the memsize of PT_TLS.

This is cleaner than computing relocations as if we had done it.

While at it, keep a single Phdr variable instead of multiple fields of it.

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

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=252352&r1=252351&r2=252352&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Nov  6 16:14:44 2015
@@ -660,7 +660,7 @@ typename ELFFile<ELFT>::uintX_t lld::elf
     InputSectionBase<ELFT> &SC = DR.Section;
     if (DR.Sym.getType() == STT_TLS)
       return SC.OutSec->getVA() + SC.getOffset(DR.Sym) -
-             Out<ELFT>::TlsInitImageVA;
+             Out<ELFT>::TlsPhdr->p_vaddr;
     return SC.OutSec->getVA() + SC.getOffset(DR.Sym);
   }
   case SymbolBody::DefinedCommonKind:

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=252352&r1=252351&r2=252352&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Nov  6 16:14:44 2015
@@ -352,6 +352,7 @@ private:
 // until Writer is initialized.
 template <class ELFT> struct Out {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
   static DynamicSection<ELFT> *Dynamic;
   static GnuHashTableSection<ELFT> *GnuHashTab;
   static GotPltSection<ELFT> *GotPlt;
@@ -369,8 +370,7 @@ template <class ELFT> struct Out {
   static StringTableSection<ELFT> *StrTab;
   static SymbolTableSection<ELFT> *DynSymTab;
   static SymbolTableSection<ELFT> *SymTab;
-  static uintX_t TlsInitImageVA;
-  static size_t TlsInitImageAlignedSize;
+  static Elf_Phdr *TlsPhdr;
 };
 
 template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
@@ -390,8 +390,7 @@ template <class ELFT> StringTableSection
 template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::StrTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
-template <class ELFT> typename Out<ELFT>::uintX_t Out<ELFT>::TlsInitImageVA;
-template <class ELFT> size_t Out<ELFT>::TlsInitImageAlignedSize;
+template <class ELFT> typename Out<ELFT>::Elf_Phdr *Out<ELFT>::TlsPhdr;
 
 } // namespace elf2
 } // namespace lld

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=252352&r1=252351&r2=252352&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Nov  6 16:14:44 2015
@@ -351,7 +351,7 @@ void X86_64TargetInfo::relocateOne(uint8
     write32le(Loc, SA);
     break;
   case R_X86_64_TPOFF32: {
-    uint64_t Val = SA - Out<ELF64LE>::TlsInitImageAlignedSize;
+    uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz;
     if (!isInt<32>(Val))
       error("R_X86_64_TPOFF32 out of range");
     write32le(Loc, Val);

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=252352&r1=252351&r2=252352&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Nov  6 16:14:44 2015
@@ -715,10 +715,8 @@ template <class ELFT> void Writer<ELFT>:
       }
 
       if (Sec->getFlags() & SHF_TLS) {
-        if (!TlsPhdr.p_vaddr) {
+        if (!TlsPhdr.p_vaddr)
           setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign());
-          Out<ELFT>::TlsInitImageVA = VA;
-        }
         if (Sec->getType() != SHT_NOBITS)
           VA = RoundUpToAlignment(VA, Sec->getAlign());
         uintX_t TVA = RoundUpToAlignment(VA + ThreadBSSOffset, Sec->getAlign());
@@ -750,9 +748,11 @@ template <class ELFT> void Writer<ELFT>:
   }
 
   if (TlsPhdr.p_vaddr) {
+    // The TLS pointer goes after PT_TLS. At least glibc will align it,
+    // so round up the size to make sure the offsets are correct.
+    TlsPhdr.p_memsz = RoundUpToAlignment(TlsPhdr.p_memsz, TlsPhdr.p_align);
     Phdrs[++PhdrIdx] = TlsPhdr;
-    Out<ELFT>::TlsInitImageAlignedSize =
-        RoundUpToAlignment(TlsPhdr.p_memsz, TlsPhdr.p_align);
+    Out<ELFT>::TlsPhdr = &Phdrs[PhdrIdx];
   }
 
   // Add an entry for .dynamic.

Added: lld/trunk/test/elf2/tls-align.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls-align.s?rev=252352&view=auto
==============================================================================
--- lld/trunk/test/elf2/tls-align.s (added)
+++ lld/trunk/test/elf2/tls-align.s Fri Nov  6 16:14:44 2015
@@ -0,0 +1,21 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld2 %t -o %tout -shared
+// RUN: llvm-readobj -program-headers %tout | FileCheck %s
+
+        .section        .tbss,"awT", at nobits
+        .align  8
+        .long   0
+
+// CHECK:      ProgramHeader {
+// CHECK:        Type: PT_TLS
+// CHECK-NEXT:   Offset:
+// CHECK-NEXT:   VirtualAddress:
+// CHECK-NEXT:   PhysicalAddress:
+// CHECK-NEXT:   FileSize: 0
+// CHECK-NEXT:   MemSize: 8
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:     PF_R (0x4)
+// CHECK-NEXT:   ]
+// CHECK-NEXT:   Alignment: 8
+// CHECK-NEXT: }




More information about the llvm-commits mailing list