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() { Index: test/COFF/header-size.s =================================================================== --- test/COFF/header-size.s +++ 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