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, 300 insertions, 322 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index a3dfccd0a12..fc075df3900 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -239,9 +239,14 @@ protected: /// in memory) and 8 byte entry data size. class DataDirectoryChunk : public AtomChunk { public: - DataDirectoryChunk(const DefinedAtom *atom) : AtomChunk(kindDataDirectory) { - if (atom) - _atomLayouts.push_back(new (_alloc) AtomLayout(atom, 0, 0)); + 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; + } + } } virtual uint64_t size() const { @@ -303,63 +308,107 @@ 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 GenericSectionChunk represents various sections such as .text or -// .data. -class GenericSectionChunk : public SectionChunk { +// \brief A TextSectionChunk represents a .text section. +class TextSectionChunk : public SectionChunk { public: virtual void write(uint8_t *fileBuffer); - 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(); + TextSectionChunk(const File &linkedFile) + : SectionChunk(".text", characteristics) { + buildContents(linkedFile, [](const DefinedAtom *atom) { + return atom->contentType() == DefinedAtom::typeCode; + }); } private: - 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"); - } + // 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_); + }); } + +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. @@ -617,16 +666,11 @@ void DataDirectoryChunk::write(uint8_t *fileBuffer) { } llvm::object::coff_section &SectionChunk::getSectionHeader() { - 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(); - } + // 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; } @@ -646,7 +690,7 @@ void SectionChunk::appendAtom(const DefinedAtom *atom) { } SectionChunk::SectionChunk(StringRef sectionName, uint32_t characteristics) - : AtomChunk(kindSection), _characteristics(characteristics), + : AtomChunk(kindSection), _sectionHeader(createSectionHeader(sectionName, characteristics)) { // The section should be aligned to disk sector. _align = SECTOR_SIZE; @@ -697,20 +741,16 @@ SectionChunk::createSectionHeader(StringRef sectionName, return header; } -void GenericSectionChunk::write(uint8_t *fileBuffer) { +void TextSectionChunk::write(uint8_t *fileBuffer) { if (_atomLayouts.empty()) return; - 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); - } + // 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); } @@ -821,7 +861,7 @@ private: void addChunk(Chunk *chunk); void addSectionChunk(SectionChunk *chunk, SectionHeaderTableChunk *table); void setImageSizeOnDisk(); - void setAddressOfEntryPoint(SectionChunk *text, PEHeaderChunk *peHeader); + void setAddressOfEntryPoint(TextSectionChunk *text, PEHeaderChunk *peHeader); uint64_t calcSectionSize(llvm::COFF::SectionCharacteristics sectionType); uint64_t calcSizeOfInitializedData() { @@ -854,87 +894,36 @@ 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(dataDirAtom); + auto *dataDirectory = new DataDirectoryChunk(linkedFile); 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); - 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); + // 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); // 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 @@ -953,10 +942,14 @@ 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) + if (text->size()) { peHeader->setBaseOfCode(text->getVirtualAddress()); - if (data) + } + if (rdata->size()) { + peHeader->setBaseOfData(rdata->getVirtualAddress()); + } else if (data->size()) { peHeader->setBaseOfData(data->getVirtualAddress()); + } peHeader->setSizeOfInitializedData(calcSizeOfInitializedData()); peHeader->setSizeOfUninitializedData(calcSizeOfUninitializedData()); peHeader->setNumberOfSections(_numSections); @@ -1034,7 +1027,7 @@ void ExecutableWriter::setImageSizeOnDisk() { } } -void ExecutableWriter::setAddressOfEntryPoint(SectionChunk *text, +void ExecutableWriter::setAddressOfEntryPoint(TextSectionChunk *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 ae23f5298ce..2131c7df081 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: .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: Name: .text CHECK-NEXT: VirtualSize: 0x1001 + +CHECK: Name: .data +CHECK-NEXT: VirtualSize: 0x6 diff --git a/lld/test/pecoff/base-reloc.test b/lld/test/pecoff/base-reloc.test index 67c1de67aa9..4b81171c23d 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 00200000 0c000000 07300c30 00000000 +BASEREL-SECTION-NEXT: 3000 00100000 0c000000 07300c30 00000000 .........0.0.... NOBASEREL-SECTION-NOT: Contents of section .reloc: diff --git a/lld/test/pecoff/bss-section.test b/lld/test/pecoff/bss-section.test index 8054df23569..f686e12d722 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: 1 +CHECK: Number: 2 CHECK-NEXT: Name: .bss CHECK-NEXT: VirtualSize: 0x0 -CHECK-NEXT: VirtualAddress: 0x1000 +CHECK-NEXT: VirtualAddress: 0x2000 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 b7620e33744..fb3d14793c9 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: 1 -CHECK-NEXT: Name: .bss (2E 62 73 73 00 00 00 00) +CHECK: Number: 2 +CHECK-NEXT: Name: .bss CHECK-NEXT: VirtualSize: 0x0 -CHECK-NEXT: VirtualAddress: 0x1000 +CHECK-NEXT: VirtualAddress: 0x2000 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 b0ea3bb7042..b2f6172a5bd 100644 --- a/lld/test/pecoff/hello.test +++ b/lld/test/pecoff/hello.test @@ -13,41 +13,42 @@ FILE: } # RUN: -- %t.obj \ # RUN: && llvm-readobj -sections %t1 | FileCheck -check-prefix=SECTIONS %s -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: } +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: ] diff --git a/lld/test/pecoff/importlib.test b/lld/test/pecoff/importlib.test index 5ea86f1744d..9aefbdcd02e 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: 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 +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 diff --git a/lld/test/pecoff/lib.test b/lld/test/pecoff/lib.test index ac94efafc00..b18351cd016 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: 2000: a1 04 10 40 00 movl 4198404, %eax -CHECK: 2005: 03 05 00 10 40 00 addl 4198400, %eax -CHECK: 200b: c3 ret +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 diff --git a/lld/test/pecoff/multi.test b/lld/test/pecoff/multi.test index fe6cdabf8db..debbce13733 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: movl {{[0-9]+}}, %eax -CHECK: addl {{[0-9]+}}, %eax -CHECK: ret +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 diff --git a/lld/test/pecoff/reloc.test b/lld/test/pecoff/reloc.test index 194dd8d5f70..bfef4600376 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: 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 +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 diff --git a/lld/test/pecoff/trivial.test b/lld/test/pecoff/trivial.test index 723ba3e620e..8d48aa5eba9 100644 --- a/lld/test/pecoff/trivial.test +++ b/lld/test/pecoff/trivial.test @@ -12,90 +12,74 @@ # RUN: -- %t.obj \ # RUN: && llvm-readobj -sections %t1 | FileCheck -check-prefix=SECTIONS %s -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 +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: } -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: ] +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: ] |