summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-07-31 22:40:35 +0000
committerRui Ueyama <ruiu@google.com>2014-07-31 22:40:35 +0000
commit140f6029ced5a1df254ea53435104a0e97069994 (patch)
treea6cfa9e4b48a6b6c04e4b95f178e9fd7adc7ff61
parent9e5298549eeaf117a46757070086c023a81033e9 (diff)
downloadbcm5719-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.cpp19
-rw-r--r--lld/test/pecoff/alignment.test2
-rw-r--r--lld/test/pecoff/associative.test2
-rw-r--r--lld/test/pecoff/base-reloc.test2
-rw-r--r--lld/test/pecoff/bss-section.test4
-rw-r--r--lld/test/pecoff/hello.test6
-rw-r--r--lld/test/pecoff/merge-largest.test2
-rw-r--r--lld/test/pecoff/merge-same-size.test2
-rw-r--r--lld/test/pecoff/nonstandard-sections.test8
-rw-r--r--lld/test/pecoff/pe32plus.test2
-rw-r--r--lld/test/pecoff/section-renaming.test6
-rw-r--r--lld/test/pecoff/trivial.test4
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
OpenPOWER on IntegriCloud