diff options
author | Rui Ueyama <ruiu@google.com> | 2014-07-31 22:40:35 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2014-07-31 22:40:35 +0000 |
commit | 140f6029ced5a1df254ea53435104a0e97069994 (patch) | |
tree | a6cfa9e4b48a6b6c04e4b95f178e9fd7adc7ff61 | |
parent | 9e5298549eeaf117a46757070086c023a81033e9 (diff) | |
download | bcm5719-llvm-140f6029ced5a1df254ea53435104a0e97069994.tar.gz bcm5719-llvm-140f6029ced5a1df254ea53435104a0e97069994.zip |
[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.
llvm-svn: 214453
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 19 | ||||
-rw-r--r-- | lld/test/pecoff/alignment.test | 2 | ||||
-rw-r--r-- | lld/test/pecoff/associative.test | 2 | ||||
-rw-r--r-- | lld/test/pecoff/base-reloc.test | 2 | ||||
-rw-r--r-- | lld/test/pecoff/bss-section.test | 4 | ||||
-rw-r--r-- | lld/test/pecoff/hello.test | 6 | ||||
-rw-r--r-- | lld/test/pecoff/merge-largest.test | 2 | ||||
-rw-r--r-- | lld/test/pecoff/merge-same-size.test | 2 | ||||
-rw-r--r-- | lld/test/pecoff/nonstandard-sections.test | 8 | ||||
-rw-r--r-- | lld/test/pecoff/pe32plus.test | 2 | ||||
-rw-r--r-- | lld/test/pecoff/section-renaming.test | 6 | ||||
-rw-r--r-- | lld/test/pecoff/trivial.test | 4 |
12 files changed, 33 insertions, 26 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index 22dd2f01ca9..07642dbc510 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -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::createSectionHeader(SectionChunk *chunk) { 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(const File &linkedFile, 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; } diff --git a/lld/test/pecoff/alignment.test b/lld/test/pecoff/alignment.test index f3d8d0661f0..78f1c97a8ca 100644 --- a/lld/test/pecoff/alignment.test +++ b/lld/test/pecoff/alignment.test @@ -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 diff --git a/lld/test/pecoff/associative.test b/lld/test/pecoff/associative.test index f998befd007..6c4eaf0f7f1 100644 --- a/lld/test/pecoff/associative.test +++ b/lld/test/pecoff/associative.test @@ -7,4 +7,4 @@ # RUN: obj2yaml %t.exe | FileCheck %s CHECK: - Name: .CRT -CHECK: SectionData: '77777777' +CHECK: SectionData: '777777770000 diff --git a/lld/test/pecoff/base-reloc.test b/lld/test/pecoff/base-reloc.test index 15c3a0226b1..8b2246f9125 100644 --- a/lld/test/pecoff/base-reloc.test +++ b/lld/test/pecoff/base-reloc.test @@ -38,7 +38,7 @@ BASEREL-HEADER: BaseRelocationTableSize: 0xC 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 diff --git a/lld/test/pecoff/bss-section.test b/lld/test/pecoff/bss-section.test index d45baab176e..4181e994fbf 100644 --- a/lld/test/pecoff/bss-section.test +++ b/lld/test/pecoff/bss-section.test @@ -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 diff --git a/lld/test/pecoff/hello.test b/lld/test/pecoff/hello.test index 3760fd554d7..679b8b3ad98 100644 --- a/lld/test/pecoff/hello.test +++ b/lld/test/pecoff/hello.test @@ -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 diff --git a/lld/test/pecoff/merge-largest.test b/lld/test/pecoff/merge-largest.test index 73d2d940660..c3ee96ca9c5 100644 --- a/lld/test/pecoff/merge-largest.test +++ b/lld/test/pecoff/merge-largest.test @@ -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 diff --git a/lld/test/pecoff/merge-same-size.test b/lld/test/pecoff/merge-same-size.test index a7c8c9f4596..c2918a2bc1a 100644 --- a/lld/test/pecoff/merge-same-size.test +++ b/lld/test/pecoff/merge-same-size.test @@ -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 diff --git a/lld/test/pecoff/nonstandard-sections.test b/lld/test/pecoff/nonstandard-sections.test index 27c5fb38ba6..2ca18162923 100644 --- a/lld/test/pecoff/nonstandard-sections.test +++ b/lld/test/pecoff/nonstandard-sections.test @@ -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 diff --git a/lld/test/pecoff/pe32plus.test b/lld/test/pecoff/pe32plus.test index fcd14aa3293..652e647ed75 100644 --- a/lld/test/pecoff/pe32plus.test +++ b/lld/test/pecoff/pe32plus.test @@ -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 diff --git a/lld/test/pecoff/section-renaming.test b/lld/test/pecoff/section-renaming.test index 6b84a0d9fea..d4fc154693a 100644 --- a/lld/test/pecoff/section-renaming.test +++ b/lld/test/pecoff/section-renaming.test @@ -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 diff --git a/lld/test/pecoff/trivial.test b/lld/test/pecoff/trivial.test index 6f149d0b21b..b9e3bcbd2c1 100644 --- a/lld/test/pecoff/trivial.test +++ b/lld/test/pecoff/trivial.test @@ -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 |