[lld] r214453 - [PECOFF] Fix section header.

Rui Ueyama ruiu at google.com
Thu Jul 31 15:40:35 PDT 2014


Author: ruiu
Date: Thu Jul 31 17:40:35 2014
New Revision: 214453

URL: http://llvm.org/viewvc/llvm-project?rev=214453&view=rev
Log:
[PECOFF] Fix section header.

The PE/COFF spec says that SizeOfRawData field in the section
header must be a multiple of FileAlignment from the optional
header. LLD emits 512 as FileAlignment, so it must have been
a multiple of 512.

LLD did not follow that. It emitted the actual section size
without the last padding as the SizeOfRawData. Although it's
not correct as per the spec, the Windows loader doesn't seem
to actually bother to check that. Executables created by LLD
worked fine.

However, tools dealing with executalbe files may expect it
to be the correct value, and one instance of it is mt.exe
tool distributed as a part of Windows SDK.

If CMake is invoked with "-E vs_link_exe" option, it silently
run mt.exe to embed a resource file to the resulting file.
And mt.exe sometimes breaks an input file if it's section
header does not follow the standard. That caused a misterous
error that CMake with Ninja occasionally produces a broken
executable.

This patch fixes the section header to make mt.exe and
other tools happy.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
    lld/trunk/test/pecoff/alignment.test
    lld/trunk/test/pecoff/associative.test
    lld/trunk/test/pecoff/base-reloc.test
    lld/trunk/test/pecoff/bss-section.test
    lld/trunk/test/pecoff/hello.test
    lld/trunk/test/pecoff/merge-largest.test
    lld/trunk/test/pecoff/merge-same-size.test
    lld/trunk/test/pecoff/nonstandard-sections.test
    lld/trunk/test/pecoff/pe32plus.test
    lld/trunk/test/pecoff/section-renaming.test
    lld/trunk/test/pecoff/trivial.test

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Thu Jul 31 17:40:35 2014
@@ -75,6 +75,7 @@ public:
   virtual ~Chunk() {}
   virtual void write(uint8_t *buffer) = 0;
   virtual uint64_t size() const { return _size; }
+  virtual uint64_t onDiskSize() const { return size(); }
   virtual uint64_t align() const { return 1; }
 
   uint64_t fileOffset() const { return _fileOffset; }
@@ -175,6 +176,12 @@ private:
 
 class SectionChunk : public Chunk {
 public:
+  uint64_t onDiskSize() const override {
+    if (_characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+      return 0;
+    return llvm::RoundUpToAlignment(size(), SECTOR_SIZE);
+  }
+
   uint64_t align() const override { return SECTOR_SIZE; }
   uint32_t getCharacteristics() const { return _characteristics; }
   StringRef getSectionName() const { return _sectionName; }
@@ -730,19 +737,18 @@ SectionHeaderTableChunk::createSectionHe
                std::min(sizeof(header.Name), sectionName.size()));
 
   uint32_t characteristics = chunk->getCharacteristics();
+  header.VirtualSize = chunk->size();
   header.VirtualAddress = chunk->getVirtualAddress();
+  header.SizeOfRawData = chunk->onDiskSize();
   header.PointerToRelocations = 0;
   header.PointerToLinenumbers = 0;
   header.NumberOfRelocations = 0;
   header.NumberOfLinenumbers = 0;
-  header.SizeOfRawData = chunk->size();
   header.Characteristics = characteristics;
 
   if (characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
-    header.VirtualSize = 0;
     header.PointerToRawData = 0;
   } else {
-    header.VirtualSize = chunk->size();
     header.PointerToRawData = chunk->fileOffset();
   }
   return header;
@@ -1018,7 +1024,8 @@ std::error_code PECOFFWriter::writeFile(
     this->build<llvm::object::pe32_header>(linkedFile);
   }
 
-  uint64_t totalSize = _chunks.back()->fileOffset() + _chunks.back()->size();
+  uint64_t totalSize =
+      _chunks.back()->fileOffset() + _chunks.back()->onDiskSize();
   std::unique_ptr<llvm::FileOutputBuffer> buffer;
   std::error_code ec = llvm::FileOutputBuffer::create(
       path, totalSize, buffer, llvm::FileOutputBuffer::F_executable);
@@ -1144,7 +1151,7 @@ void PECOFFWriter::setImageSizeOnDisk()
     _imageSizeOnDisk =
         llvm::RoundUpToAlignment(_imageSizeOnDisk, chunk->align());
     chunk->setFileOffset(_imageSizeOnDisk);
-    _imageSizeOnDisk += chunk->size();
+    _imageSizeOnDisk += chunk->onDiskSize();
   }
 }
 
@@ -1154,7 +1161,7 @@ uint64_t PECOFFWriter::calcSectionSize(
   for (auto &cp : _chunks)
     if (SectionChunk *chunk = dyn_cast<SectionChunk>(&*cp))
       if (chunk->getCharacteristics() & sectionType)
-        ret += chunk->size();
+        ret += chunk->onDiskSize();
   return ret;
 }
 

Modified: lld/trunk/test/pecoff/alignment.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/alignment.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/alignment.test (original)
+++ lld/trunk/test/pecoff/alignment.test Thu Jul 31 17:40:35 2014
@@ -5,7 +5,7 @@
 # RUN: llvm-readobj -sections %t.exe | FileCheck %s
 
 CHECK: Name: .bss (2E 62 73 73 00 00 00 00)
-CHECK: RawDataSize: 18
+CHECK: RawDataSize: 0
 
 CHECK:      Name: .data (2E 64 61 74 61 00 00 00)
 CHECK-NEXT: VirtualSize: 0x6

Modified: lld/trunk/test/pecoff/associative.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/associative.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/associative.test (original)
+++ lld/trunk/test/pecoff/associative.test Thu Jul 31 17:40:35 2014
@@ -7,4 +7,4 @@
 # RUN: obj2yaml %t.exe | FileCheck %s
 
 CHECK: - Name: .CRT
-CHECK:   SectionData: '77777777'
+CHECK:   SectionData: '777777770000

Modified: lld/trunk/test/pecoff/base-reloc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/base-reloc.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/base-reloc.test (original)
+++ lld/trunk/test/pecoff/base-reloc.test Thu Jul 31 17:40:35 2014
@@ -38,7 +38,7 @@ BASEREL-HEADER:     BaseRelocationTableS
 BASEREL-HEADER:     Name: .reloc (2E 72 65 6C 6F 63 00 00)
 BASEREL-HEADER-NEXT:     VirtualSize: 0xC
 BASEREL-HEADER-NEXT:     VirtualAddress: 0x3000
-BASEREL-HEADER-NEXT:     RawDataSize: 12
+BASEREL-HEADER-NEXT:     RawDataSize: 512
 BASEREL-HEADER-NEXT:     PointerToRawData: 0x600
 BASEREL-HEADER-NEXT:     PointerToRelocations: 0x0
 BASEREL-HEADER-NEXT:     PointerToLineNumbers: 0x0

Modified: lld/trunk/test/pecoff/bss-section.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/bss-section.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/bss-section.test (original)
+++ lld/trunk/test/pecoff/bss-section.test Thu Jul 31 17:40:35 2014
@@ -5,9 +5,9 @@
 CHECK:       Section {
 CHECK:         Number: 1
 CHECK-NEXT:    Name: .bss
-CHECK-NEXT:    VirtualSize: 0x0
+CHECK-NEXT:    VirtualSize: 0x320
 CHECK-NEXT:    VirtualAddress: 0x1000
-CHECK-NEXT:    RawDataSize: 800
+CHECK-NEXT:    RawDataSize: 0
 CHECK-NEXT:    PointerToRawData: 0x0
 CHECK-NEXT:    PointerToRelocations: 0x0
 CHECK-NEXT:    PointerToLineNumbers: 0x0

Modified: lld/trunk/test/pecoff/hello.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/hello.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/hello.test (original)
+++ lld/trunk/test/pecoff/hello.test Thu Jul 31 17:40:35 2014
@@ -4,7 +4,7 @@
 # RUN: llvm-readobj -file-headers %t1.exe | FileCheck -check-prefix=FILE %s
 
 FILE: ImageOptionalHeader {
-FILE:   SizeOfInitializedData: 30
+FILE:   SizeOfInitializedData: 1024
 FILE:   SizeOfHeaders: 512
 FILE: }
 
@@ -20,7 +20,7 @@ SECTIONS-NEXT:     Number: 1
 SECTIONS-NEXT:     Name: .data
 SECTIONS-NEXT:     VirtualSize: 0x12
 SECTIONS-NEXT:     VirtualAddress: 0x1000
-SECTIONS-NEXT:     RawDataSize: 18
+SECTIONS-NEXT:     RawDataSize: 512
 SECTIONS-NEXT:     PointerToRawData: 0x200
 SECTIONS-NEXT:     PointerToRelocations: 0x0
 SECTIONS-NEXT:     PointerToLineNumbers: 0x0
@@ -37,7 +37,7 @@ SECTIONS-NEXT:     Number: 2
 SECTIONS-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
 SECTIONS-NEXT:     VirtualSize: 0x1C
 SECTIONS-NEXT:     VirtualAddress: 0x2000
-SECTIONS-NEXT:     RawDataSize: 28
+SECTIONS-NEXT:     RawDataSize: 512
 SECTIONS-NEXT:     PointerToRawData: 0x400
 SECTIONS-NEXT:     PointerToRelocations: 0x0
 SECTIONS-NEXT:     PointerToLineNumbers: 0x0

Modified: lld/trunk/test/pecoff/merge-largest.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/merge-largest.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/merge-largest.test (original)
+++ lld/trunk/test/pecoff/merge-largest.test Thu Jul 31 17:40:35 2014
@@ -21,4 +21,4 @@ READOBJ-NEXT:     Number: 1
 READOBJ-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
 READOBJ-NEXT:     VirtualSize: 0x8
 READOBJ-NEXT:     VirtualAddress: 0x1000
-READOBJ-NEXT:     RawDataSize: 8
+READOBJ-NEXT:     RawDataSize: 512

Modified: lld/trunk/test/pecoff/merge-same-size.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/merge-same-size.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/merge-same-size.test (original)
+++ lld/trunk/test/pecoff/merge-same-size.test Thu Jul 31 17:40:35 2014
@@ -29,4 +29,4 @@ READOBJ-NEXT:     Number: 1
 READOBJ-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
 READOBJ-NEXT:     VirtualSize: 0x7
 READOBJ-NEXT:     VirtualAddress: 0x1000
-READOBJ-NEXT:     RawDataSize: 7
+READOBJ-NEXT:     RawDataSize: 512

Modified: lld/trunk/test/pecoff/nonstandard-sections.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/nonstandard-sections.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/nonstandard-sections.test (original)
+++ lld/trunk/test/pecoff/nonstandard-sections.test Thu Jul 31 17:40:35 2014
@@ -10,7 +10,7 @@ CHECK-NEXT:     Number: 1
 CHECK-NEXT:     Name: .bar (2E 62 61 72 00 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x4
 CHECK-NEXT:     VirtualAddress: 0x1000
-CHECK-NEXT:     RawDataSize: 4
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0x400
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0
@@ -26,7 +26,7 @@ CHECK-NEXT:     Number: 2
 CHECK-NEXT:     Name: .data (2E 64 61 74 61 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x4
 CHECK-NEXT:     VirtualAddress: 0x2000
-CHECK-NEXT:     RawDataSize: 4
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0x600
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0
@@ -43,7 +43,7 @@ CHECK-NEXT:     Number: 3
 CHECK-NEXT:     Name: .foo (2E 66 6F 6F 00 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x4
 CHECK-NEXT:     VirtualAddress: 0x3000
-CHECK-NEXT:     RawDataSize: 4
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0x800
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0
@@ -60,7 +60,7 @@ CHECK-NEXT:     Number: 4
 CHECK-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x4
 CHECK-NEXT:     VirtualAddress: 0x4000
-CHECK-NEXT:     RawDataSize: 4
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0xA00
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0

Modified: lld/trunk/test/pecoff/pe32plus.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/pe32plus.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/pe32plus.test (original)
+++ lld/trunk/test/pecoff/pe32plus.test Thu Jul 31 17:40:35 2014
@@ -22,7 +22,7 @@ CHECK-NEXT: }
 CHECK-NEXT: ImageOptionalHeader {
 CHECK-NEXT:   MajorLinkerVersion: 0
 CHECK-NEXT:   MinorLinkerVersion: 0
-CHECK-NEXT:   SizeOfCode: 1
+CHECK-NEXT:   SizeOfCode: 512
 CHECK-NEXT:   SizeOfInitializedData: 0
 CHECK-NEXT:   SizeOfUninitializedData: 0
 CHECK-NEXT:   AddressOfEntryPoint: 0x1000

Modified: lld/trunk/test/pecoff/section-renaming.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/section-renaming.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/section-renaming.test (original)
+++ lld/trunk/test/pecoff/section-renaming.test Thu Jul 31 17:40:35 2014
@@ -12,7 +12,7 @@ CHECK-NEXT:     Number: 1
 CHECK-NEXT:     Name: .data (2E 64 61 74 61 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x4
 CHECK-NEXT:     VirtualAddress: 0x1000
-CHECK-NEXT:     RawDataSize: 4
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0x200
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0
@@ -29,7 +29,7 @@ CHECK-NEXT:     Number: 2
 CHECK-NEXT:     Name: .hoge (2E 68 6F 67 65 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x4
 CHECK-NEXT:     VirtualAddress: 0x2000
-CHECK-NEXT:     RawDataSize: 4
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0x400
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0
@@ -46,7 +46,7 @@ CHECK-NEXT:     Number: 3
 CHECK-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
 CHECK-NEXT:     VirtualSize: 0x8
 CHECK-NEXT:     VirtualAddress: 0x3000
-CHECK-NEXT:     RawDataSize: 8
+CHECK-NEXT:     RawDataSize: 512
 CHECK-NEXT:     PointerToRawData: 0x600
 CHECK-NEXT:     PointerToRelocations: 0x0
 CHECK-NEXT:     PointerToLineNumbers: 0x0

Modified: lld/trunk/test/pecoff/trivial.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/trivial.test?rev=214453&r1=214452&r2=214453&view=diff
==============================================================================
--- lld/trunk/test/pecoff/trivial.test (original)
+++ lld/trunk/test/pecoff/trivial.test Thu Jul 31 17:40:35 2014
@@ -30,7 +30,7 @@ FILE-NEXT: }
 FILE-NEXT: ImageOptionalHeader {
 FILE-NEXT:   MajorLinkerVersion: 0
 FILE-NEXT:   MinorLinkerVersion: 0
-FILE-NEXT:   SizeOfCode: 6
+FILE-NEXT:   SizeOfCode: 512
 FILE-NEXT:   SizeOfInitializedData: 0
 FILE-NEXT:   SizeOfUninitializedData: 0
 FILE-NEXT:   AddressOfEntryPoint: 0x1000
@@ -69,7 +69,7 @@ SECTIONS-NEXT:     Number: 1
 SECTIONS-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
 SECTIONS-NEXT:     VirtualSize: 0x6
 SECTIONS-NEXT:     VirtualAddress: 0x1000
-SECTIONS-NEXT:     RawDataSize: 6
+SECTIONS-NEXT:     RawDataSize: 512
 SECTIONS-NEXT:     PointerToRawData: 0x200
 SECTIONS-NEXT:     PointerToRelocations: 0x0
 SECTIONS-NEXT:     PointerToLineNumbers: 0x0





More information about the llvm-commits mailing list