diff options
author | Rui Ueyama <ruiu@google.com> | 2013-11-27 00:55:45 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2013-11-27 00:55:45 +0000 |
commit | 3e873b0578f99b700b9860ed3501804d83e2cc5c (patch) | |
tree | 4d4f55029b9579381f771854c05790ba068aa251 | |
parent | 6ef2bb02f5ac76a90ae2d35438d06a1e3f604beb (diff) | |
download | bcm5719-llvm-3e873b0578f99b700b9860ed3501804d83e2cc5c.tar.gz bcm5719-llvm-3e873b0578f99b700b9860ed3501804d83e2cc5c.zip |
[PECOFF] Add a generic section writer.
Instead of having multiple SectionChunks for each section (.text, .data,
.rdata and .bss), we could have one chunk writer that can emit any sections.
This patch does that -- removing all section-sepcific chunk writers and
replace them with one "generic" writer.
This change should simplify the code because it eliminates similar-but-
slightly-different classes.
It also fixes an issue in the previous design. Before this patch, we could
emit only limited set of sections (i.e. .text, .data, .rdata and .bss). With
this patch, we can emit any sections.
llvm-svn: 195797
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 277 | ||||
-rw-r--r-- | lld/test/pecoff/alignment.test | 8 | ||||
-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/common-symbol.test | 6 | ||||
-rw-r--r-- | lld/test/pecoff/hello.test | 77 | ||||
-rw-r--r-- | lld/test/pecoff/importlib.test | 24 | ||||
-rw-r--r-- | lld/test/pecoff/lib.test | 6 | ||||
-rw-r--r-- | lld/test/pecoff/multi.test | 6 | ||||
-rw-r--r-- | lld/test/pecoff/reloc.test | 56 | ||||
-rw-r--r-- | lld/test/pecoff/trivial.test | 156 |
11 files changed, 322 insertions, 300 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index fc075df3900..a3dfccd0a12 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -239,14 +239,9 @@ protected: /// in memory) and 8 byte entry data size. class DataDirectoryChunk : public AtomChunk { public: - DataDirectoryChunk(const File &linkedFile) : AtomChunk(kindDataDirectory) { - // Find the data directory atom. - for (const DefinedAtom *atom : linkedFile.defined()) { - if (atom->contentType() == DefinedAtom::typeDataDirectoryEntry) { - _atomLayouts.push_back(new (_alloc) AtomLayout(atom, 0, 0)); - return; - } - } + DataDirectoryChunk(const DefinedAtom *atom) : AtomChunk(kindDataDirectory) { + if (atom) + _atomLayouts.push_back(new (_alloc) AtomLayout(atom, 0, 0)); } virtual uint64_t size() const { @@ -308,107 +303,63 @@ protected: void buildContents(const File &linkedFile, bool (*isEligible)(const DefinedAtom *)); + const uint32_t _characteristics; + + llvm::object::coff_section _sectionHeader; private: llvm::object::coff_section createSectionHeader(StringRef sectionName, uint32_t characteristics) const; - llvm::object::coff_section _sectionHeader; mutable llvm::BumpPtrAllocator _alloc; }; -// \brief A TextSectionChunk represents a .text section. -class TextSectionChunk : public SectionChunk { +// \brief A GenericSectionChunk represents various sections such as .text or +// .data. +class GenericSectionChunk : public SectionChunk { public: virtual void write(uint8_t *fileBuffer); - TextSectionChunk(const File &linkedFile) - : SectionChunk(".text", characteristics) { - buildContents(linkedFile, [](const DefinedAtom *atom) { - return atom->contentType() == DefinedAtom::typeCode; - }); + GenericSectionChunk(StringRef name, + const std::vector<const DefinedAtom *> &atoms) + : SectionChunk(name, getCharacteristics(name, atoms)) { + for (auto *a : atoms) + appendAtom(a); + _sectionHeader.VirtualSize = _size; + _sectionHeader.SizeOfRawData = size(); } private: - // When loaded into memory, text section should be readable and executable. - static const uint32_t characteristics = - llvm::COFF::IMAGE_SCN_CNT_CODE | llvm::COFF::IMAGE_SCN_MEM_EXECUTE | - llvm::COFF::IMAGE_SCN_MEM_READ; -}; - -// \brief A RDataSectionChunk represents a .rdata section. -class RDataSectionChunk : public SectionChunk { -public: - RDataSectionChunk(const File &linkedFile) - : SectionChunk(".rdata", characteristics) { - buildContents(linkedFile, [](const DefinedAtom *atom) { - return (atom->contentType() == DefinedAtom::typeData && - atom->permissions() == DefinedAtom::permR__); - }); - } - -private: - // When loaded into memory, rdata section should be readable. - static const uint32_t characteristics = - llvm::COFF::IMAGE_SCN_MEM_READ | - llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; -}; - -// \brief A DataSectionChunk represents a .data section. -class DataSectionChunk : public SectionChunk { -public: - DataSectionChunk(const File &linkedFile) - : SectionChunk(".data", characteristics) { - buildContents(linkedFile, [](const DefinedAtom *atom) { - return (atom->contentType() == DefinedAtom::typeData && - atom->permissions() == DefinedAtom::permRW_); - }); + uint32_t getCharacteristics(StringRef name, + const std::vector<const DefinedAtom *> &atoms) { + const uint32_t code = llvm::COFF::IMAGE_SCN_CNT_CODE; + const uint32_t execute = llvm::COFF::IMAGE_SCN_MEM_EXECUTE; + const uint32_t read = llvm::COFF::IMAGE_SCN_MEM_READ; + const uint32_t write = llvm::COFF::IMAGE_SCN_MEM_WRITE; + const uint32_t data = llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; + const uint32_t bss = llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; + if (name == ".text") + return code | execute | read; + if (name == ".data") + return data | read | write; + if (name == ".rdata") + return data | read; + if (name == ".bss") + return bss | read | write; + assert(atoms.size() > 0); + switch (atoms[0]->permissions()) { + case DefinedAtom::permR__: + return data | read; + case DefinedAtom::permRW_: + return data | read | write; + case DefinedAtom::permR_X: + return code | execute | read; + case DefinedAtom::permRWX: + return code | execute | read | write; + default: + llvm_unreachable("Unsupported permission"); + } } - -private: - // When loaded into memory, data section should be readable and writable. - static const uint32_t characteristics = - llvm::COFF::IMAGE_SCN_MEM_READ | - llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - llvm::COFF::IMAGE_SCN_MEM_WRITE; -}; - -// \brief A BSSSectionChunk represents a .bss section. -// -// Seems link.exe does not emit .bss section but instead merges it with .data -// section. In COFF, if the size of the section in the header is greater than -// the size of the actual data on disk, the section on memory is zero-padded. -// That's why .bss can be merge with .data just by appending it at the end of -// the section. -// -// The executable with .bss is also valid and easier to understand. So we chose -// to create .bss in LLD. -class BssSectionChunk : public SectionChunk { -public: - // BSS section does not have contents, so write should be no-op. - virtual void write(uint8_t *fileBuffer) {} - - virtual llvm::object::coff_section &getSectionHeader() { - llvm::object::coff_section §ionHeader = - SectionChunk::getSectionHeader(); - sectionHeader.VirtualSize = 0; - sectionHeader.PointerToRawData = 0; - return sectionHeader; - } - - BssSectionChunk(const File &linkedFile) - : SectionChunk(".bss", characteristics) { - buildContents(linkedFile, [](const DefinedAtom *atom) { - return atom->contentType() == DefinedAtom::typeZeroFill; - }); - } - -private: - // When loaded into memory, bss section should be readable and writable. - static const uint32_t characteristics = - llvm::COFF::IMAGE_SCN_MEM_READ | - llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | - llvm::COFF::IMAGE_SCN_MEM_WRITE; }; /// A BaseRelocAtom represents a base relocation block in ".reloc" section. @@ -666,11 +617,16 @@ void DataDirectoryChunk::write(uint8_t *fileBuffer) { } llvm::object::coff_section &SectionChunk::getSectionHeader() { - // Fix up section size before returning it. VirtualSize should be the size - // of the actual content, and SizeOfRawData should be aligned to the section - // alignment. - _sectionHeader.VirtualSize = _size; - _sectionHeader.SizeOfRawData = size(); + if (_characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) { + _sectionHeader.VirtualSize = 0; + _sectionHeader.PointerToRawData = 0; + } else { + // Fix up section size before returning it. VirtualSize should be the size + // of the actual content, and SizeOfRawData should be aligned to the section + // alignment. + _sectionHeader.VirtualSize = _size; + _sectionHeader.SizeOfRawData = size(); + } return _sectionHeader; } @@ -690,7 +646,7 @@ void SectionChunk::appendAtom(const DefinedAtom *atom) { } SectionChunk::SectionChunk(StringRef sectionName, uint32_t characteristics) - : AtomChunk(kindSection), + : AtomChunk(kindSection), _characteristics(characteristics), _sectionHeader(createSectionHeader(sectionName, characteristics)) { // The section should be aligned to disk sector. _align = SECTOR_SIZE; @@ -741,16 +697,20 @@ SectionChunk::createSectionHeader(StringRef sectionName, return header; } -void TextSectionChunk::write(uint8_t *fileBuffer) { +void GenericSectionChunk::write(uint8_t *fileBuffer) { if (_atomLayouts.empty()) return; - // Fill the section with INT 3 (0xCC) rather than NUL, so that the - // disassembler will not interpret a garbage between atoms as the beginning - // of multi-byte machine code. This does not change the behavior of - // resulting binary but help debugging. - uint8_t *start = fileBuffer + _atomLayouts.front()->_fileOffset; - uint8_t *end = fileBuffer + _atomLayouts.back()->_fileOffset; - memset(start, 0xCC, end - start); + if (_characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) + return; + if (_characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE) { + // Fill the section with INT 3 (0xCC) rather than NUL, so that the + // disassembler will not interpret a garbage between atoms as the beginning + // of multi-byte machine code. This does not change the behavior of + // resulting binary but help debugging. + uint8_t *start = fileBuffer + _atomLayouts.front()->_fileOffset; + uint8_t *end = fileBuffer + _atomLayouts.back()->_fileOffset; + memset(start, 0xCC, end - start); + } SectionChunk::write(fileBuffer); } @@ -861,7 +821,7 @@ private: void addChunk(Chunk *chunk); void addSectionChunk(SectionChunk *chunk, SectionHeaderTableChunk *table); void setImageSizeOnDisk(); - void setAddressOfEntryPoint(TextSectionChunk *text, PEHeaderChunk *peHeader); + void setAddressOfEntryPoint(SectionChunk *text, PEHeaderChunk *peHeader); uint64_t calcSectionSize(llvm::COFF::SectionCharacteristics sectionType); uint64_t calcSizeOfInitializedData() { @@ -894,36 +854,87 @@ private: std::map<const Atom *, uint64_t> atomRva; }; +StringRef customSectionName(const DefinedAtom *atom) { + assert(atom->sectionChoice() == DefinedAtom::sectionCustomRequired); + StringRef s = atom->customSectionName(); + size_t pos = s.find('$'); + return (pos == StringRef::npos) ? s : s.substr(0, pos); +} + +StringRef chooseSectionByContent(const DefinedAtom *atom) { + switch (atom->contentType()) { + case DefinedAtom::typeCode: + return ".text"; + case DefinedAtom::typeZeroFill: + return ".bss"; + case DefinedAtom::typeData: + if (atom->permissions() == DefinedAtom::permR__) + return ".rdata"; + if (atom->permissions() == DefinedAtom::permRW_) + return ".data"; + break; + default: + break; + } + llvm::errs() << "Atom: contentType=" << atom->contentType() + << " permission=" << atom->permissions() << "\n"; + llvm_unreachable("Failed to choose section based on content"); +} + +typedef std::map<StringRef, std::vector<const DefinedAtom *> > AtomVectorMap; + +void groupAtoms(const File &file, AtomVectorMap &result, + const DefinedAtom *&datadir) { + for (const DefinedAtom *atom : file.defined()) { + if (atom->sectionChoice() == DefinedAtom::sectionCustomRequired) { + result[customSectionName(atom)].push_back(atom); + continue; + } + if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) { + if (atom->contentType() == DefinedAtom::typeDataDirectoryEntry) { + datadir = atom; + } else { + result[chooseSectionByContent(atom)].push_back(atom); + } + continue; + } + llvm_unreachable("Unknown section choice"); + } +} + // Create all chunks that consist of the output file. void ExecutableWriter::build(const File &linkedFile) { + AtomVectorMap atoms; + const DefinedAtom *dataDirAtom = nullptr; + groupAtoms(linkedFile, atoms, dataDirAtom); + // Create file chunks and add them to the list. auto *dosStub = new DOSStubChunk(_PECOFFLinkingContext); auto *peHeader = new PEHeaderChunk(_PECOFFLinkingContext); - auto *dataDirectory = new DataDirectoryChunk(linkedFile); + auto *dataDirectory = new DataDirectoryChunk(dataDirAtom); auto *sectionTable = new SectionHeaderTableChunk(); - auto *text = new TextSectionChunk(linkedFile); - auto *rdata = new RDataSectionChunk(linkedFile); - auto *data = new DataSectionChunk(linkedFile); - auto *bss = new BssSectionChunk(linkedFile); - BaseRelocChunk *baseReloc = nullptr; - if (_PECOFFLinkingContext.getBaseRelocationEnabled()) - baseReloc = new BaseRelocChunk(linkedFile); - addChunk(dosStub); addChunk(peHeader); addChunk(dataDirectory); addChunk(sectionTable); - // Do not add the empty section. Windows loader does not like a section of - // size zero and rejects such executable. - if (text->size()) - addSectionChunk(text, sectionTable); - if (rdata->size()) - addSectionChunk(rdata, sectionTable); - if (data->size()) - addSectionChunk(data, sectionTable); - if (bss->size()) - addSectionChunk(bss, sectionTable); + SectionChunk *text = nullptr; + SectionChunk *data = nullptr; + for (auto i : atoms) { + StringRef sectionName = i.first; + std::vector<const DefinedAtom *> &contents = i.second; + auto *section = new GenericSectionChunk(sectionName, contents); + addSectionChunk(section, sectionTable); + + if (!text && sectionName == ".text") + text = section; + else if (!data && (sectionName == ".data" || sectionName == ".rdata")) + data = section; + } + + BaseRelocChunk *baseReloc = nullptr; + if (_PECOFFLinkingContext.getBaseRelocationEnabled()) + baseReloc = new BaseRelocChunk(linkedFile); // Now that we know the addresses of all defined atoms that needs to be // relocated. So we can create the ".reloc" section which contains all the @@ -942,14 +953,10 @@ void ExecutableWriter::build(const File &linkedFile) { // Now that we know the size and file offset of sections. Set the file // header accordingly. peHeader->setSizeOfCode(calcSizeOfCode()); - if (text->size()) { + if (text) peHeader->setBaseOfCode(text->getVirtualAddress()); - } - if (rdata->size()) { - peHeader->setBaseOfData(rdata->getVirtualAddress()); - } else if (data->size()) { + if (data) peHeader->setBaseOfData(data->getVirtualAddress()); - } peHeader->setSizeOfInitializedData(calcSizeOfInitializedData()); peHeader->setSizeOfUninitializedData(calcSizeOfUninitializedData()); peHeader->setNumberOfSections(_numSections); @@ -1027,7 +1034,7 @@ void ExecutableWriter::setImageSizeOnDisk() { } } -void ExecutableWriter::setAddressOfEntryPoint(TextSectionChunk *text, +void ExecutableWriter::setAddressOfEntryPoint(SectionChunk *text, PEHeaderChunk *peHeader) { // Find the virtual address of the entry point symbol if any. // PECOFF spec says that entry point for dll images is optional, in which diff --git a/lld/test/pecoff/alignment.test b/lld/test/pecoff/alignment.test index 2131c7df081..ae23f5298ce 100644 --- a/lld/test/pecoff/alignment.test +++ b/lld/test/pecoff/alignment.test @@ -3,8 +3,8 @@ # RUN: lld -flavor link /out:%t1 /subsystem:console /force /entry:start \ # RUN: -- %t.obj && llvm-readobj -sections %t1 | FileCheck %s -CHECK: Name: .text -CHECK-NEXT: VirtualSize: 0x1001 - -CHECK: Name: .data +CHECK: Name: .data (2E 64 61 74 61 00 00 00) CHECK-NEXT: VirtualSize: 0x6 + +CHECK: Name: .text (2E 74 65 78 74 00 00 00) +CHECK-NEXT: VirtualSize: 0x1001 diff --git a/lld/test/pecoff/base-reloc.test b/lld/test/pecoff/base-reloc.test index 4b81171c23d..67c1de67aa9 100644 --- a/lld/test/pecoff/base-reloc.test +++ b/lld/test/pecoff/base-reloc.test @@ -15,7 +15,7 @@ # objdump does. BASEREL-SECTION: Contents of section .reloc: -BASEREL-SECTION-NEXT: 3000 00100000 0c000000 07300c30 00000000 .........0.0.... +BASEREL-SECTION-NEXT: 3000 00200000 0c000000 07300c30 00000000 NOBASEREL-SECTION-NOT: Contents of section .reloc: diff --git a/lld/test/pecoff/bss-section.test b/lld/test/pecoff/bss-section.test index f686e12d722..8054df23569 100644 --- a/lld/test/pecoff/bss-section.test +++ b/lld/test/pecoff/bss-section.test @@ -2,10 +2,10 @@ # RUN: -- %p/Inputs/bss.obj && llvm-readobj -sections %t | FileCheck %s CHECK: Section { -CHECK: Number: 2 +CHECK: Number: 1 CHECK-NEXT: Name: .bss CHECK-NEXT: VirtualSize: 0x0 -CHECK-NEXT: VirtualAddress: 0x2000 +CHECK-NEXT: VirtualAddress: 0x1000 CHECK-NEXT: RawDataSize: 1024 CHECK-NEXT: PointerToRawData: 0x0 CHECK-NEXT: PointerToRelocations: 0x0 diff --git a/lld/test/pecoff/common-symbol.test b/lld/test/pecoff/common-symbol.test index fb3d14793c9..b7620e33744 100644 --- a/lld/test/pecoff/common-symbol.test +++ b/lld/test/pecoff/common-symbol.test @@ -4,10 +4,10 @@ # RUN: -- %t.obj %t.obj && llvm-readobj -sections %t | FileCheck %s CHECK: Section { -CHECK: Number: 2 -CHECK-NEXT: Name: .bss +CHECK: Number: 1 +CHECK-NEXT: Name: .bss (2E 62 73 73 00 00 00 00) CHECK-NEXT: VirtualSize: 0x0 -CHECK-NEXT: VirtualAddress: 0x2000 +CHECK-NEXT: VirtualAddress: 0x1000 CHECK-NEXT: RawDataSize: 512 CHECK-NEXT: PointerToRawData: 0x0 CHECK-NEXT: PointerToRelocations: 0x0 diff --git a/lld/test/pecoff/hello.test b/lld/test/pecoff/hello.test index b2f6172a5bd..b0ea3bb7042 100644 --- a/lld/test/pecoff/hello.test +++ b/lld/test/pecoff/hello.test @@ -13,42 +13,41 @@ FILE: } # RUN: -- %t.obj \ # RUN: && llvm-readobj -sections %t1 | FileCheck -check-prefix=SECTIONS %s -SECTIONS: Format: COFF-i386 -SECTIONS: Arch: i386 -SECTIONS: AddressSize: 32bit -SECTIONS: Sections [ -SECTIONS: Section { -SECTIONS: Number: 1 -SECTIONS: Name: .text (2E 74 65 78 74 00 00 00) -SECTIONS: VirtualSize: 0x1C -SECTIONS: VirtualAddress: 0x1000 -SECTIONS: RawDataSize: 512 -SECTIONS: PointerToRawData: 0x200 -SECTIONS: PointerToRelocations: 0x0 -SECTIONS: PointerToLineNumbers: 0x0 -SECTIONS: RelocationCount: 0 -SECTIONS: LineNumberCount: 0 -SECTIONS: Characteristics [ (0x60000020) -SECTIONS: IMAGE_SCN_CNT_CODE (0x20) -SECTIONS: IMAGE_SCN_MEM_EXECUTE (0x20000000) -SECTIONS: IMAGE_SCN_MEM_READ (0x40000000) -SECTIONS: ] -SECTIONS: } -SECTIONS: Section { -SECTIONS: Number: 2 -SECTIONS: Name: .data (2E 64 61 74 61 00 00 00) -SECTIONS: VirtualSize: 0x12 -SECTIONS: VirtualAddress: 0x2000 -SECTIONS: RawDataSize: 512 -SECTIONS: PointerToRawData: 0x400 -SECTIONS: PointerToRelocations: 0x0 -SECTIONS: PointerToLineNumbers: 0x0 -SECTIONS: RelocationCount: 0 -SECTIONS: LineNumberCount: 0 -SECTIONS: Characteristics [ (0xC0000040) -SECTIONS: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -SECTIONS: IMAGE_SCN_MEM_READ (0x40000000) -SECTIONS: IMAGE_SCN_MEM_WRITE (0x80000000) -SECTIONS: ] -SECTIONS: } -SECTIONS: ] +SECTIONS: Format: COFF-i386 +SECTIONS-NEXT: Arch: i386 +SECTIONS-NEXT: AddressSize: 32bit +SECTIONS-NEXT: Sections [ +SECTIONS-NEXT: Section { +SECTIONS-NEXT: Number: 1 +SECTIONS-NEXT: Name: .data +SECTIONS-NEXT: VirtualSize: 0x12 +SECTIONS-NEXT: VirtualAddress: 0x1000 +SECTIONS-NEXT: RawDataSize: 512 +SECTIONS-NEXT: PointerToRawData: 0x200 +SECTIONS-NEXT: PointerToRelocations: 0x0 +SECTIONS-NEXT: PointerToLineNumbers: 0x0 +SECTIONS-NEXT: RelocationCount: 0 +SECTIONS-NEXT: LineNumberCount: 0 +SECTIONS-NEXT: Characteristics [ +SECTIONS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +SECTIONS-NEXT: IMAGE_SCN_MEM_READ +SECTIONS-NEXT: IMAGE_SCN_MEM_WRITE +SECTIONS-NEXT: ] +SECTIONS-NEXT: } +SECTIONS-NEXT: Section { +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: 512 +SECTIONS-NEXT: PointerToRawData: 0x400 +SECTIONS-NEXT: PointerToRelocations: 0x0 +SECTIONS-NEXT: PointerToLineNumbers: 0x0 +SECTIONS-NEXT: RelocationCount: 0 +SECTIONS-NEXT: LineNumberCount: 0 +SECTIONS-NEXT: Characteristics [ +SECTIONS-NEXT: IMAGE_SCN_CNT_CODE +SECTIONS-NEXT: IMAGE_SCN_MEM_EXECUTE +SECTIONS-NEXT: IMAGE_SCN_MEM_READ +SECTIONS-NEXT: ] +SECTIONS-NEXT: } diff --git a/lld/test/pecoff/importlib.test b/lld/test/pecoff/importlib.test index 9aefbdcd02e..5ea86f1744d 100644 --- a/lld/test/pecoff/importlib.test +++ b/lld/test/pecoff/importlib.test @@ -24,15 +24,15 @@ CHECK: Disassembly of section .text: CHECK-NEXT: .text: -CHECK-NEXT: 1000: 55 pushl %ebp -CHECK-NEXT: 1001: 8b ec movl %esp, %ebp -CHECK-NEXT: 1003: 56 pushl %esi -CHECK-NEXT: 1004: {{[0-9 a-f]+}} calll *{{[0-9a-f]+}} -CHECK-NEXT: 100a: {{[0-9 a-f]+}} movl {{[0-9a-f]+}}, %ecx -CHECK-NEXT: 1010: 8b 31 movl (%ecx), %esi -CHECK-NEXT: 1012: 03 f0 addl %eax, %esi -CHECK-NEXT: 1014: {{[0-9 a-f]+}} calll *{{[0-9a-f]+}} -CHECK-NEXT: 101a: 03 c6 addl %esi, %eax -CHECK-NEXT: 101c: 5e popl %esi -CHECK-NEXT: 101d: 5d popl %ebp -CHECK-NEXT: 101e: c3 ret +CHECK-NEXT: pushl %ebp +CHECK-NEXT: movl %esp, %ebp +CHECK-NEXT: pushl %esi +CHECK-NEXT: calll *{{[0-9]+}} +CHECK-NEXT: movl {{[0-9]+}}, %ecx +CHECK-NEXT: movl (%ecx), %esi +CHECK-NEXT: addl %eax, %esi +CHECK-NEXT: calll *{{[0-9]+}} +CHECK-NEXT: addl %esi, %eax +CHECK-NEXT: popl %esi +CHECK-NEXT: popl %ebp +CHECK-NEXT: ret diff --git a/lld/test/pecoff/lib.test b/lld/test/pecoff/lib.test index b18351cd016..ac94efafc00 100644 --- a/lld/test/pecoff/lib.test +++ b/lld/test/pecoff/lib.test @@ -7,6 +7,6 @@ CHECK: Disassembly of section .text: CHECK: .text: -CHECK: 1000: a1 04 20 40 00 movl 4202500, %eax -CHECK: 1005: 03 05 00 20 40 00 addl 4202496, %eax -CHECK: 100b: c3 ret +CHECK: 2000: a1 04 10 40 00 movl 4198404, %eax +CHECK: 2005: 03 05 00 10 40 00 addl 4198400, %eax +CHECK: 200b: c3 ret diff --git a/lld/test/pecoff/multi.test b/lld/test/pecoff/multi.test index debbce13733..fe6cdabf8db 100644 --- a/lld/test/pecoff/multi.test +++ b/lld/test/pecoff/multi.test @@ -9,6 +9,6 @@ CHECK: Disassembly of section .text: CHECK: .text: -CHECK: 1000: a1 04 20 40 00 movl 4202500, %eax -CHECK: 1005: 03 05 00 20 40 00 addl 4202496, %eax -CHECK: 100b: c3 ret +CHECK: movl {{[0-9]+}}, %eax +CHECK: addl {{[0-9]+}}, %eax +CHECK: ret diff --git a/lld/test/pecoff/reloc.test b/lld/test/pecoff/reloc.test index bfef4600376..194dd8d5f70 100644 --- a/lld/test/pecoff/reloc.test +++ b/lld/test/pecoff/reloc.test @@ -7,34 +7,34 @@ BEFORE: Disassembly of section .text: BEFORE: _main: -BEFORE: 0: 55 -BEFORE: 1: 89 e5 -BEFORE: 3: 83 ec 14 -BEFORE: 6: c7 45 fc 00 00 00 00 -BEFORE: d: c7 44 24 0c 00 00 00 00 -BEFORE: 15: c7 44 24 08 07 00 00 00 -BEFORE: 1d: c7 44 24 04 00 00 00 00 -BEFORE: 25: c7 04 24 00 00 00 00 -BEFORE: 2c: ff 15 00 00 00 00 -BEFORE: 32: 83 ec 10 -BEFORE: 35: 31 c0 -BEFORE: 37: 83 c4 14 -BEFORE: 3a: 5d -BEFORE: 3b: c3 +BEFORE: 0: 55 +BEFORE: 1: 89 e5 +BEFORE: 3: 83 ec 14 +BEFORE: 6: c7 45 fc 00 00 00 00 +BEFORE: d: c7 44 24 0c 00 00 00 00 +BEFORE: 15: c7 44 24 08 07 00 00 00 +BEFORE: 1d: c7 44 24 04 00 00 00 00 +BEFORE: 25: c7 04 24 00 00 00 00 +BEFORE: 2c: ff 15 00 00 00 00 +BEFORE: 32: 83 ec 10 +BEFORE: 35: 31 c0 +BEFORE: 37: 83 c4 14 +BEFORE: 3a: 5d +BEFORE: 3b: c3 AFTER: Disassembly of section .text: AFTER: .text: -AFTER: 1000: 55 -AFTER: 1001: 89 e5 -AFTER: 1003: 83 ec 14 -AFTER: 1006: c7 45 fc 00 00 00 00 -AFTER: 100d: c7 44 24 0c 00 00 00 00 -AFTER: 1015: c7 44 24 08 07 20 40 00 -AFTER: 101d: c7 44 24 04 00 20 40 00 -AFTER: 1025: c7 04 24 00 00 00 00 -AFTER: 102c: ff 15 00 00 40 00 -AFTER: 1032: 83 ec 10 -AFTER: 1035: 31 c0 -AFTER: 1037: 83 c4 14 -AFTER: 103a: 5d -AFTER: 103b: c3 +AFTER: pushl %ebp +AFTER: movl %esp, %ebp +AFTER: subl $20, %esp +AFTER: movl $0, -4(%ebp) +AFTER: movl $0, 12(%esp) +AFTER: movl $4198407, 8(%esp) +AFTER: movl $4198400, 4(%esp) +AFTER: movl $0, (%esp) +AFTER: calll *4194304 +AFTER: subl $16, %esp +AFTER: xorl %eax, %eax +AFTER: addl $20, %esp +AFTER: popl %ebp +AFTER: ret diff --git a/lld/test/pecoff/trivial.test b/lld/test/pecoff/trivial.test index 8d48aa5eba9..723ba3e620e 100644 --- a/lld/test/pecoff/trivial.test +++ b/lld/test/pecoff/trivial.test @@ -12,74 +12,90 @@ # RUN: -- %t.obj \ # RUN: && llvm-readobj -sections %t1 | FileCheck -check-prefix=SECTIONS %s -FILE: Format: COFF-i386 -FILE: Arch: i386 -FILE: AddressSize: 32bit -FILE: ImageFileHeader { -FILE: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) -FILE: SectionCount: 1 -FILE: TimeDateStamp: -FILE: PointerToSymbolTable: 0x0 -FILE: SymbolCount: 0 -FILE: OptionalHeaderSize: 224 -FILE: Characteristics [ (0x102) -FILE: IMAGE_FILE_32BIT_MACHINE (0x100) -FILE: IMAGE_FILE_EXECUTABLE_IMAGE (0x2) -FILE: ] -FILE: } -FILE: ImageOptionalHeader { -FILE: MajorLinkerVersion: 0 -FILE: MinorLinkerVersion: 0 -FILE: SizeOfCode: 512 -FILE: SizeOfInitializedData: 0 -FILE: SizeOfUninitializedData: 0 -FILE: AddressOfEntryPoint: 0x1000 -FILE: BaseOfCode: 0x1000 -FILE: BaseOfData: 0 -FILE: ImageBase: 0x400000 -FILE: SectionAlignment: 4096 -FILE: FileAlignment: 512 -FILE: MajorOperatingSystemVersion: 3 -FILE: MinorOperatingSystemVersion: 11 -FILE: MajorImageVersion: 1 -FILE: MinorImageVersion: 25 -FILE: MajorSubsystemVersion: 3 -FILE: MinorSubsystemVersion: 11 -FILE: SizeOfImage: 8192 -FILE: SizeOfHeaders: 512 -FILE: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) -FILE: Subsystem [ (0x8540) -FILE: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40) -FILE: IMAGE_DLL_CHARACTERISTICS_NO_SEH (0x400) -FILE: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100) -FILE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000) -FILE: ] -FILE: SizeOfStackReserve: 1048576 -FILE: SizeOfStackCommit: 4096 -FILE: SizeOfHeapReserve: 1048576 -FILE: SizeOfHeapCommit: 4096 -FILE: NumberOfRvaAndSize: 16 -FILE: } +FILE: Format: COFF-i386 +FILE-NEXT: Arch: i386 +FILE-NEXT: AddressSize: 32bit +FILE-NEXT: ImageFileHeader { +FILE-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) +FILE-NEXT: SectionCount: 2 +FILE-NEXT: TimeDateStamp: +FILE-NEXT: PointerToSymbolTable: 0x0 +FILE-NEXT: SymbolCount: 0 +FILE-NEXT: OptionalHeaderSize: 224 +FILE-NEXT: Characteristics [ (0x102) +FILE-NEXT: IMAGE_FILE_32BIT_MACHINE (0x100) +FILE-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2) +FILE-NEXT: ] +FILE-NEXT: } +FILE-NEXT: ImageOptionalHeader { +FILE-NEXT: MajorLinkerVersion: 0 +FILE-NEXT: MinorLinkerVersion: 0 +FILE-NEXT: SizeOfCode: 512 +FILE-NEXT: SizeOfInitializedData: 0 +FILE-NEXT: SizeOfUninitializedData: 0 +FILE-NEXT: AddressOfEntryPoint: 0x1000 +FILE-NEXT: BaseOfCode: 0x1000 +FILE-NEXT: BaseOfData: 0 +FILE-NEXT: ImageBase: 0x400000 +FILE-NEXT: SectionAlignment: 4096 +FILE-NEXT: FileAlignment: 512 +FILE-NEXT: MajorOperatingSystemVersion: 3 +FILE-NEXT: MinorOperatingSystemVersion: 11 +FILE-NEXT: MajorImageVersion: 1 +FILE-NEXT: MinorImageVersion: 25 +FILE-NEXT: MajorSubsystemVersion: 3 +FILE-NEXT: MinorSubsystemVersion: 11 +FILE-NEXT: SizeOfImage: 8192 +FILE-NEXT: SizeOfHeaders: 512 +FILE-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) +FILE-NEXT: Subsystem [ (0x8540) +FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40) +FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_NO_SEH (0x400) +FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100) +FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000) +FILE-NEXT: ] +FILE-NEXT: SizeOfStackReserve: 1048576 +FILE-NEXT: SizeOfStackCommit: 4096 +FILE-NEXT: SizeOfHeapReserve: 1048576 +FILE-NEXT: SizeOfHeapCommit: 4096 +FILE-NEXT: NumberOfRvaAndSize: 16 -SECTIONS: Format: COFF-i386 -SECTIONS: Arch: i386 -SECTIONS: AddressSize: 32bit -SECTIONS: Sections [ -SECTIONS: Section { -SECTIONS: Number: 1 -SECTIONS: Name: .text (2E 74 65 78 74 00 00 00) -SECTIONS: VirtualSize: 0x6 -SECTIONS: VirtualAddress: 0x1000 -SECTIONS: RawDataSize: 512 -SECTIONS: PointerToRawData: 0x200 -SECTIONS: PointerToRelocations: 0x0 -SECTIONS: PointerToLineNumbers: 0x0 -SECTIONS: RelocationCount: 0 -SECTIONS: LineNumberCount: 0 -SECTIONS: Characteristics [ (0x60000020) -SECTIONS: IMAGE_SCN_CNT_CODE (0x20) -SECTIONS: IMAGE_SCN_MEM_EXECUTE (0x20000000) -SECTIONS: IMAGE_SCN_MEM_READ (0x40000000) -SECTIONS: ] -SECTIONS: } -SECTIONS: ] +SECTIONS: Format: COFF-i386 +SECTIONS-NEXT: Arch: i386 +SECTIONS-NEXT: AddressSize: 32bit +SECTIONS-NEXT: Sections [ +SECTIONS-NEXT: Section { +SECTIONS-NEXT: Number: 1 +SECTIONS-NEXT: Name: .data (2E 64 61 74 61 00 00 00) +SECTIONS-NEXT: VirtualSize: 0x0 +SECTIONS-NEXT: VirtualAddress: 0x1000 +SECTIONS-NEXT: RawDataSize: 0 +SECTIONS-NEXT: PointerToRawData: 0x200 +SECTIONS-NEXT: PointerToRelocations: 0x0 +SECTIONS-NEXT: PointerToLineNumbers: 0x0 +SECTIONS-NEXT: RelocationCount: 0 +SECTIONS-NEXT: LineNumberCount: 0 +SECTIONS-NEXT: Characteristics [ +SECTIONS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +SECTIONS-NEXT: IMAGE_SCN_MEM_READ +SECTIONS-NEXT: IMAGE_SCN_MEM_WRITE +SECTIONS-NEXT: ] +SECTIONS-NEXT: } +SECTIONS-NEXT: Section { +SECTIONS-NEXT: Number: 2 +SECTIONS-NEXT: Name: .text (2E 74 65 78 74 00 00 00) +SECTIONS-NEXT: VirtualSize: 0x6 +SECTIONS-NEXT: VirtualAddress: 0x1000 +SECTIONS-NEXT: RawDataSize: 512 +SECTIONS-NEXT: PointerToRawData: 0x200 +SECTIONS-NEXT: PointerToRelocations: 0x0 +SECTIONS-NEXT: PointerToLineNumbers: 0x0 +SECTIONS-NEXT: RelocationCount: 0 +SECTIONS-NEXT: LineNumberCount: 0 +SECTIONS-NEXT: Characteristics [ +SECTIONS-NEXT: IMAGE_SCN_CNT_CODE +SECTIONS-NEXT: IMAGE_SCN_MEM_EXECUTE +SECTIONS-NEXT: IMAGE_SCN_MEM_READ +SECTIONS-NEXT: ] +SECTIONS-NEXT: } +SECTIONS-NEXT: ] |