[PATCH] D54495: [LLD] [COFF] Remove empty sections before calculating the size of section headers

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 14 03:53:12 PST 2018


mstorsjo updated this revision to Diff 174012.
mstorsjo added a comment.

Updated to not remove RelocSec prematurely, and to not remove sections that contain MergeChunks, as these get their size allocated later (in assignAddresses).

At this point, this ended more messy than I intended first, so I'm not sure if this is worth it any more.


https://reviews.llvm.org/D54495

Files:
  COFF/Writer.cpp
  test/COFF/header-size.s


Index: test/COFF/header-size.s
===================================================================
--- /dev/null
+++ test/COFF/header-size.s
@@ -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
Index: COFF/Writer.cpp
===================================================================
--- COFF/Writer.cpp
+++ COFF/Writer.cpp
@@ -173,6 +173,7 @@
   void createExportTable();
   void mergeSections();
   void readRelocTargets();
+  void removeUnusedSections();
   void assignAddresses();
   void finalizeAddresses();
   void removeEmptySections();
@@ -500,6 +501,7 @@
   createExportTable();
   mergeSections();
   readRelocTargets();
+  removeUnusedSections();
   finalizeAddresses();
   removeEmptySections();
   setSectionPermissions();
@@ -882,6 +884,21 @@
     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() {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54495.174012.patch
Type: text/x-patch
Size: 1978 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181114/58c7a648/attachment.bin>


More information about the llvm-commits mailing list