diff options
-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: ] |