[lld] r260465 - Don't include NOBITS TLS in PT_LOAD.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 10 15:29:39 PST 2016


Author: rafael
Date: Wed Feb 10 17:29:38 2016
New Revision: 260465

URL: http://llvm.org/viewvc/llvm-project?rev=260465&view=rev
Log:
Don't include NOBITS TLS in PT_LOAD.

They don't count for the memory or file size, so this is mostly just a
simplification.

The only noticeable difference should be fewer empty program headers.

Added:
    lld/trunk/test/ELF/avoid-empty-program-headers.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=260465&r1=260464&r2=260465&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Feb 10 17:29:38 2016
@@ -1184,8 +1184,16 @@ void Writer<ELFT>::addStartStopSymbols(O
       Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
 }
 
-template <class ELFT> static bool needsPhdr(OutputSectionBase<ELFT> *Sec) {
-  return Sec->getFlags() & SHF_ALLOC;
+template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
+  if (!(Sec->getFlags() & SHF_ALLOC))
+    return false;
+
+  // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
+  // responsible for allocating space for them, not the PT_LOAD that
+  // contains the TLS initialization image.
+  if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS)
+    return false;
+  return true;
 }
 
 static uint32_t toPhdrFlags(uint64_t Flags) {
@@ -1241,9 +1249,18 @@ template <class ELFT> void Writer<ELFT>:
   Phdr TlsHdr(PT_TLS, PF_R);
   Phdr RelRo(PT_GNU_RELRO, PF_R);
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
-    if (!needsPhdr<ELFT>(Sec))
+    if (!(Sec->getFlags() & SHF_ALLOC))
       break;
 
+    // If we meet TLS section then we create TLS header
+    // and put all TLS sections inside for futher use when
+    // assign addresses.
+    if (Sec->getFlags() & SHF_TLS)
+      AddSec(TlsHdr, Sec);
+
+    if (!needsPtLoad<ELFT>(Sec))
+      continue;
+
     // If flags changed then we want new load segment.
     uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
     if (Flags != NewFlags) {
@@ -1252,14 +1269,6 @@ template <class ELFT> void Writer<ELFT>:
       Load = AddHdr(LoadType, NewFlags);
       Flags = NewFlags;
     }
-    // If we meet TLS section then we create TLS header
-    // and put all TLS sections inside for futher use when
-    // assign addresses.
-    if (Sec->getFlags() & SHF_TLS) {
-      AddSec(TlsHdr, Sec);
-      if (Sec->getType() == SHT_NOBITS)
-        continue;
-    }
 
     AddSec(*Load, Sec);
 
@@ -1307,18 +1316,15 @@ template <class ELFT> void Writer<ELFT>:
   SmallPtrSet<OutputSectionBase<ELFT> *, 4> PageAlign;
   for (const Phdr &P : Phdrs) {
     if (P.H.p_type == PT_GNU_RELRO) {
-      // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD
-      // and is not tls, we have to align it to a page. We don't have to
-      // align tls since TLS NOBITS takes no space.
+      // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
+      // have to align it to a page.
       auto I = std::find(OutputSections.begin(), OutputSections.end(), P.Last);
       ++I;
-      if (I != OutputSections.end() && needsPhdr(*I) &&
-          !((*I)->getFlags() & SHF_TLS))
+      if (I != OutputSections.end() && needsPtLoad(*I))
         PageAlign.insert(*I);
     }
 
-    // FIXME: why create empty PT_LOAD?
-    if (P.H.p_type == PT_LOAD && P.First)
+    if (P.H.p_type == PT_LOAD)
       PageAlign.insert(P.First);
   }
 
@@ -1337,21 +1343,15 @@ template <class ELFT> void Writer<ELFT>:
       FileOff += Sec->getSize();
 
     // We only assign VAs to allocated sections.
-    if (needsPhdr<ELFT>(Sec)) {
-      // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
-      // responsible for allocating space for them, not the PT_LOAD that
-      // contains the TLS initialization image.
-      bool IsTls = Sec->getFlags() & SHF_TLS;
-      if (IsTls && Sec->getType() == SHT_NOBITS) {
-        uintX_t TVA = VA + ThreadBssOffset;
-        TVA = alignTo(TVA, Align);
-        Sec->setVA(TVA);
-        ThreadBssOffset = TVA - VA + Sec->getSize();
-      } else {
-        VA = alignTo(VA, Align);
-        Sec->setVA(VA);
-        VA += Sec->getSize();
-      }
+    if (needsPtLoad<ELFT>(Sec)) {
+      VA = alignTo(VA, Align);
+      Sec->setVA(VA);
+      VA += Sec->getSize();
+    } else if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS) {
+      uintX_t TVA = VA + ThreadBssOffset;
+      TVA = alignTo(TVA, Align);
+      Sec->setVA(TVA);
+      ThreadBssOffset = TVA - VA + Sec->getSize();
     }
   }
 

Added: lld/trunk/test/ELF/avoid-empty-program-headers.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/avoid-empty-program-headers.s?rev=260465&view=auto
==============================================================================
--- lld/trunk/test/ELF/avoid-empty-program-headers.s (added)
+++ lld/trunk/test/ELF/avoid-empty-program-headers.s Wed Feb 10 17:29:38 2016
@@ -0,0 +1,78 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %tout
+// RUN: llvm-readobj -program-headers %tout | FileCheck %s
+
+.global _start
+_start:
+        retq
+
+.section .tbss,"awT", at nobits
+        .zero 4
+// FIXME: Test that we don't create unecessary empty PT_LOAD and PT_GNU_RELRO
+// for the .tbss section.
+
+// CHECK:      ProgramHeaders [
+// CHECK-NEXT:   ProgramHeader {
+// CHECK-NEXT:     Type: PT_PHDR (0x6)
+// CHECK-NEXT:     Offset: 0x40
+// CHECK-NEXT:     VirtualAddress: 0x10040
+// CHECK-NEXT:     PhysicalAddress: 0x10040
+// CHECK-NEXT:     FileSize: 280
+// CHECK-NEXT:     MemSize: 280
+// CHECK-NEXT:     Flags [ (0x4)
+// CHECK-NEXT:       PF_R (0x4)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Alignment: 8
+// CHECK-NEXT:   }
+// CHECK-NEXT:   ProgramHeader {
+// CHECK-NEXT:     Type: PT_LOAD (0x1)
+// CHECK-NEXT:     Offset: 0x0
+// CHECK-NEXT:     VirtualAddress: 0x10000
+// CHECK-NEXT:     PhysicalAddress: 0x10000
+// CHECK-NEXT:     FileSize: 344
+// CHECK-NEXT:     MemSize: 344
+// CHECK-NEXT:     Flags [ (0x4)
+// CHECK-NEXT:       PF_R (0x4)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Alignment: 4096
+// CHECK-NEXT:   }
+// CHECK-NEXT:   ProgramHeader {
+// CHECK-NEXT:     Type: PT_LOAD (0x1)
+// CHECK-NEXT:     Offset: 0x1000
+// CHECK-NEXT:     VirtualAddress: 0x11000
+// CHECK-NEXT:     PhysicalAddress: 0x11000
+// CHECK-NEXT:     FileSize: 1
+// CHECK-NEXT:     MemSize: 1
+// CHECK-NEXT:     Flags [ (0x5)
+// CHECK-NEXT:       PF_R (0x4)
+// CHECK-NEXT:       PF_X (0x1)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Alignment: 4096
+// CHECK-NEXT:   }
+// CHECK-NEXT:   ProgramHeader {
+// CHECK-NEXT:     Type: PT_TLS (0x7)
+// CHECK-NEXT:     Offset: 0x1001
+// CHECK-NEXT:     VirtualAddress: 0x11001
+// CHECK-NEXT:     PhysicalAddress: 0x11001
+// CHECK-NEXT:     FileSize: 0
+// CHECK-NEXT:     MemSize: 4
+// CHECK-NEXT:     Flags [ (0x4)
+// CHECK-NEXT:       PF_R (0x4)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Alignment: 1
+// CHECK-NEXT:   }
+// CHECK-NEXT:   ProgramHeader {
+// CHECK-NEXT:     Type: PT_GNU_STACK (0x6474E551)
+// CHECK-NEXT:     Offset: 0x0
+// CHECK-NEXT:     VirtualAddress: 0x0
+// CHECK-NEXT:     PhysicalAddress: 0x0
+// CHECK-NEXT:     FileSize: 0
+// CHECK-NEXT:     MemSize: 0
+// CHECK-NEXT:     Flags [ (0x6)
+// CHECK-NEXT:       PF_R (0x4)
+// CHECK-NEXT:       PF_W (0x2)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Alignment: 0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]




More information about the llvm-commits mailing list