[lld] r318924 - [ELF] Skip over empty sections when checking for contiguous relro

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 23 07:10:00 PST 2017


Author: psmith
Date: Thu Nov 23 07:10:00 2017
New Revision: 318924

URL: http://llvm.org/viewvc/llvm-project?rev=318924&view=rev
Log:
[ELF] Skip over empty sections when checking for contiguous relro

When checking for contiguous relro sections we can skip over empty sections.
If there is an empty non-relro section in the middle of a contiguous block
of relro sections then it cannot be written to so it is safe to include in
PT_GNU_RELRO header. If there is a contiguous block of empty relro sections
then no PT_GNU_RELRO header is required for them.

Differential Revision: https://reviews.llvm.org/D40364


Added:
    lld/trunk/test/ELF/relro-non-contiguous-zerosize.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=318924&r1=318923&r2=318924&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Nov 23 07:10:00 2017
@@ -1452,6 +1452,22 @@ static uint64_t computeFlags(uint64_t Fl
   return Flags;
 }
 
+// Prior to finalizeContents() an OutputSection containing SyntheticSections
+// may have 0 Size, but contain SyntheticSections that haven't had their size
+// calculated yet. We must use SyntheticSection->empty() for these sections.
+static bool isOutputSectionZeroSize(const OutputSection* Sec) {
+  if (Sec->Size > 0)
+    return false;
+  for (BaseCommand *BC : Sec->SectionCommands) {
+    if (auto *ISD = dyn_cast<InputSectionDescription>(BC))
+      for (InputSection *IS : ISD->Sections)
+        if (SyntheticSection *SS = dyn_cast<SyntheticSection>(IS))
+          if (!SS->empty())
+            return false;
+    }
+  return true;
+}
+
 // Decide which program headers to create and which sections to include in each
 // one.
 template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
@@ -1517,7 +1533,7 @@ template <class ELFT> std::vector<PhdrEn
   bool InRelroPhdr = false;
   bool IsRelroFinished = false;
   for (OutputSection *Sec : OutputSections) {
-    if (!needsPtLoad(Sec))
+    if (!needsPtLoad(Sec) || isOutputSectionZeroSize(Sec))
       continue;
     if (isRelroSection(Sec)) {
       InRelroPhdr = true;

Added: lld/trunk/test/ELF/relro-non-contiguous-zerosize.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relro-non-contiguous-zerosize.s?rev=318924&view=auto
==============================================================================
--- lld/trunk/test/ELF/relro-non-contiguous-zerosize.s (added)
+++ lld/trunk/test/ELF/relro-non-contiguous-zerosize.s Thu Nov 23 07:10:00 2017
@@ -0,0 +1,62 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o
+// RUN: ld.lld -shared %t.o %t2.o -o %t.so
+
+// Check that we ignore zero sized non-relro sections that are covered by the
+// range of addresses covered by the PT_GNU_RELRO header.
+// Check that we ignore zero sized relro sections that are disjoint from the
+// range of addresses covered by the PT_GNU_RELRO header.
+// REQUIRES: x86
+
+// RUN: echo "SECTIONS { \
+// RUN: .ctors : { *(.ctors) } \
+// RUN: .large1 : { *(.large1) } \
+// RUN: .dynamic : { *(.dynamic) } \
+// RUN: .zero_size : { *(.zero_size) } \
+// RUN: .jcr : { *(.jcr) } \
+// RUN: .got.plt : { *(.got.plt) } \
+// RUN: .large2 : { *(.large2) } \
+// RUN: .data.rel.ro : { *(.data.rel.ro.*) } \
+// RUN: } " > %t.script
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o
+// RUN: ld.lld %t3.o %t.so -o %t --script=%t.script
+// RUN: llvm-readobj -program-headers %t | FileCheck %s
+
+// CHECK: Type: PT_GNU_RELRO
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: VirtualAddress:
+// CHECK-NEXT: PhysicalAddress:
+// CHECK-NEXT: FileSize:
+// CHECK-NEXT: MemSize: 4096
+
+        .section .text, "ax", @progbits
+        .global _start
+        .global bar
+        .global foo
+_start:
+        callq bar
+
+        // page size non-relro sections that would alter PT_GNU_RELRO header
+        // MemSize if counted as part of relro.
+        .section .large1, "aw", @progbits
+        .space 4 * 1024
+
+        .section .large2, "aw", @progbits
+        .space 4 * 1024
+        
+        // empty relro section
+        .section .ctors, "aw", @progbits
+        
+        // non-empty relro section
+        .section .jcr, "aw", @progbits
+        .quad 0
+
+        // empty non-relro section
+        .section .zero_size, "aw", @progbits
+        .global sym
+sym:
+
+        // empty relro section
+        .section .data.rel.ro, "aw", @progbits
+        .global sym2
+sym2:




More information about the llvm-commits mailing list