[lld] r347704 - [COFF] Remove empty sections before calculating the size of section headers

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 27 12:48:09 PST 2018


Author: mstorsjo
Date: Tue Nov 27 12:48:09 2018
New Revision: 347704

URL: http://llvm.org/viewvc/llvm-project?rev=347704&view=rev
Log:
[COFF] Remove empty sections before calculating the size of section headers

The number of sections is used in assignAddresses (in
finalizeAddresses) and the space for all sections is permanent from
that point on, even if we later decide we won't write some of them.

The VirtualSize field also gets calculated in assignAddresses, so we
need to manually check whether the section is empty here instead.

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

Added:
    lld/trunk/test/COFF/header-size.s
Modified:
    lld/trunk/COFF/Writer.cpp

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=347704&r1=347703&r2=347704&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Tue Nov 27 12:48:09 2018
@@ -173,6 +173,7 @@ private:
   void createExportTable();
   void mergeSections();
   void readRelocTargets();
+  void removeUnusedSections();
   void assignAddresses();
   void finalizeAddresses();
   void removeEmptySections();
@@ -500,6 +501,7 @@ void Writer::run() {
   createExportTable();
   mergeSections();
   readRelocTargets();
+  removeUnusedSections();
   finalizeAddresses();
   removeEmptySections();
   setSectionPermissions();
@@ -882,6 +884,21 @@ void Writer::createExportTable() {
     EdataSec->addChunk(C);
 }
 
+void Writer::removeUnusedSections() {
+  // Remove sections that we can be sure won't get content, to avoid
+  // allocating space for their section headers.
+  auto IsUnused = [this](OutputSection *S) {
+    if (S == RelocSec)
+      return false; // This section is populated later.
+    // MergeChunks have zero size at this point, as their size is finalized
+    // later. Only remove sections that have no Chunks at all.
+    return S->Chunks.empty();
+  };
+  OutputSections.erase(
+      std::remove_if(OutputSections.begin(), OutputSections.end(), IsUnused),
+      OutputSections.end());
+}
+
 // The Windows loader doesn't seem to like empty sections,
 // so we remove them if any.
 void Writer::removeEmptySections() {

Added: lld/trunk/test/COFF/header-size.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/header-size.s?rev=347704&view=auto
==============================================================================
--- lld/trunk/test/COFF/header-size.s (added)
+++ lld/trunk/test/COFF/header-size.s Tue Nov 27 12:48:09 2018
@@ -0,0 +1,12 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe
+// RUN: llvm-readobj -sections %t.exe | FileCheck %s
+    .globl main
+main:
+    ret
+
+// Check that the first section data comes at 512 bytes in the file.
+// If the size allocated for headers would include size for section
+// headers which aren't written, PointerToRawData would be 0x400 instead.
+// CHECK: PointerToRawData: 0x200




More information about the llvm-commits mailing list