From c3899d22342fcaef6b02b22c136b3e06ea918f95 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Sat, 4 Apr 2015 19:13:32 +0000 Subject: [PATCH] [Mips] Support writing .reginfo section into the linked file In case of MIPS O32 ABI linker should merge registers usage masks stored in the input .reginfo sections and save result into the output .reginfo section. The ABI states that the .reginfo section should be put into the separate segment. This requirement is not implemented in this patch. llvm-svn: 234103 --- .../ELF/Mips/MipsDynamicLibraryWriter.h | 16 +++ lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h | 13 +- .../ELF/Mips/MipsExecutableWriter.h | 14 +++ .../ELF/Mips/MipsLinkingContext.cpp | 12 ++ .../ELF/Mips/MipsLinkingContext.h | 6 + lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h | 29 +++++ .../ReaderWriter/ELF/Mips/MipsSectionChunks.h | 47 +++++++ lld/test/CMakeLists.txt | 2 +- lld/test/elf/Mips/base-address.test | 16 --- .../elf/Mips/dynlib-fileheader-micro.test | 5 - lld/test/elf/Mips/dynlib-fileheader.test | 5 - lld/test/elf/Mips/mips-options-gp0.test | 17 ++- lld/test/elf/Mips/reginfo-01.test | 30 +++++ lld/test/elf/Mips/reginfo-02.test | 74 +++++++++++ lld/test/elf/Mips/reginfo-03.test | 40 ++++++ lld/test/elf/Mips/reginfo-04.test | 76 +++++++++++ lld/test/elf/Mips/reginfo-05.test | 118 ++++++++++++++++++ lld/test/elf/Mips/rel-gprel16.test | 12 +- lld/test/elf/Mips/rel-gprel32.test | 8 +- 19 files changed, 491 insertions(+), 49 deletions(-) create mode 100644 lld/test/elf/Mips/reginfo-01.test create mode 100644 lld/test/elf/Mips/reginfo-02.test create mode 100644 lld/test/elf/Mips/reginfo-03.test create mode 100644 lld/test/elf/Mips/reginfo-04.test create mode 100644 lld/test/elf/Mips/reginfo-05.test diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h index 034b57ca7c3e..a72a467b8087 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h @@ -13,6 +13,7 @@ #include "MipsDynamicTable.h" #include "MipsELFWriters.h" #include "MipsLinkingContext.h" +#include "MipsSectionChunks.h" namespace lld { namespace elf { @@ -32,6 +33,7 @@ protected: bool createImplicitFiles(std::vector> &) override; void finalizeDefaultAtomValues() override; + void createDefaultSections() override; std::error_code setELFHeader() override { DynamicLibraryWriter::setELFHeader(); @@ -46,6 +48,7 @@ protected: private: MipsELFWriter _writeHelper; MipsTargetLayout &_targetLayout; + unique_bump_ptr> _reginfo; }; template @@ -69,6 +72,19 @@ void MipsDynamicLibraryWriter::finalizeDefaultAtomValues() { _writeHelper.finalizeMipsRuntimeAtomValues(); } +template +void MipsDynamicLibraryWriter::createDefaultSections() { + DynamicLibraryWriter::createDefaultSections(); + const auto &mask = + static_cast(this->_ctx).getMergeReginfoMask(); + if (!ELFT::Is64Bits && mask.hasValue()) { + _reginfo = unique_bump_ptr>( + new (this->_alloc) + MipsReginfoSection(this->_ctx, _targetLayout, *mask)); + this->_layout.addSection(_reginfo.get()); + } +} + template unique_bump_ptr> MipsDynamicLibraryWriter::createSymbolTable() { diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h index 7376fb5f2cf0..92d1165595e4 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h @@ -161,6 +161,8 @@ private: typedef llvm::object::Elf_RegInfo Elf_RegInfo; typedef llvm::object::Elf_Mips_Options Elf_Mips_Options; + auto &ctx = static_cast(this->_ctx); + if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) { auto contents = this->getSectionContents(sec); if (std::error_code ec = contents.getError()) @@ -172,9 +174,12 @@ private: return make_dynamic_error_code( StringRef("Invalid size of MIPS_OPTIONS section")); - const auto *opt = reinterpret_cast(raw.data()); + const auto *opt = + reinterpret_cast(raw.data()); if (opt->kind == ODK_REGINFO) { - _gp0 = reinterpret_cast(opt + 1)->ri_gp_value; + const auto *regInfo = reinterpret_cast(opt + 1); + ctx.mergeReginfoMask(*regInfo); + _gp0 = regInfo->ri_gp_value; break; } raw = raw.slice(opt->size); @@ -189,7 +194,9 @@ private: return make_dynamic_error_code( StringRef("Invalid size of MIPS_REGINFO section")); - _gp0 = reinterpret_cast(raw.data())->ri_gp_value; + const auto *regInfo = reinterpret_cast(raw.data()); + ctx.mergeReginfoMask(*regInfo); + _gp0 = regInfo->ri_gp_value; } return std::error_code(); } diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h index 3927d69e6be6..61e2eedc5392 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h @@ -31,6 +31,7 @@ protected: bool createImplicitFiles(std::vector> &) override; void finalizeDefaultAtomValues() override; + void createDefaultSections() override; std::error_code setELFHeader() override; unique_bump_ptr> createSymbolTable() override; @@ -40,6 +41,7 @@ protected: private: MipsELFWriter _writeHelper; MipsTargetLayout &_targetLayout; + unique_bump_ptr> _reginfo; }; template @@ -122,6 +124,18 @@ void MipsExecutableWriter::finalizeDefaultAtomValues() { _writeHelper.finalizeMipsRuntimeAtomValues(); } +template void MipsExecutableWriter::createDefaultSections() { + ExecutableWriter::createDefaultSections(); + const auto &mask = + static_cast(this->_ctx).getMergeReginfoMask(); + if (!ELFT::Is64Bits && mask.hasValue()) { + _reginfo = unique_bump_ptr>( + new (this->_alloc) + MipsReginfoSection(this->_ctx, _targetLayout, *mask)); + this->_layout.addSection(_reginfo.get()); + } +} + template unique_bump_ptr> MipsExecutableWriter::createSymbolTable() { diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index ea91fcfd6de6..fcbd72471ee3 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -47,10 +47,22 @@ std::error_code MipsLinkingContext::mergeHeaderFlags(uint8_t fileClass, return _flagsMerger.mergeHeaderFlags(fileClass, flags); } +void MipsLinkingContext::mergeReginfoMask(const MipsReginfo &info) { + if (_reginfoMask.hasValue()) + _reginfoMask->merge(info); + else + _reginfoMask = info; +} + uint32_t MipsLinkingContext::getMergedELFFlags() const { return _flagsMerger.getMergedELFFlags(); } +const llvm::Optional & +MipsLinkingContext::getMergeReginfoMask() const { + return _reginfoMask; +} + uint64_t MipsLinkingContext::getBaseAddress() const { if (_baseAddress == 0 && getOutputELFType() == llvm::ELF::ET_EXEC) return getTriple().isArch64Bit() ? 0x120000000 : 0x400000; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h index f66797068668..d77ba25c9659 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h @@ -10,6 +10,7 @@ #define LLD_READER_WRITER_ELF_MIPS_MIPS_LINKING_CONTEXT_H #include "MipsELFFlagsMerger.h" +#include "MipsReginfo.h" #include "lld/ReaderWriter/ELFLinkingContext.h" namespace lld { @@ -46,7 +47,11 @@ public: MipsLinkingContext(llvm::Triple triple); std::error_code mergeHeaderFlags(uint8_t fileClass, uint64_t flags) override; + void mergeReginfoMask(const MipsReginfo &info); + uint32_t getMergedELFFlags() const; + const llvm::Optional &getMergeReginfoMask() const; + void registerRelocationNames(Registry &r) override; // ELFLinkingContext @@ -62,6 +67,7 @@ public: private: MipsELFFlagsMerger _flagsMerger; + llvm::Optional _reginfoMask; }; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h b/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h index 01552a293de4..83ccaa5e1a6a 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h @@ -47,4 +47,33 @@ template struct Elf_Mips_Options { } // end namespace object. } // end namespace llvm. +namespace lld { +namespace elf { + +struct MipsReginfo { + uint32_t _gpRegMask = 0; + uint32_t _cpRegMask[4] = {0}; + + MipsReginfo() = default; + + template MipsReginfo(const ElfReginfo &elf) { + _gpRegMask = elf.ri_gprmask; + _cpRegMask[0] = elf.ri_cprmask[0]; + _cpRegMask[1] = elf.ri_cprmask[1]; + _cpRegMask[2] = elf.ri_cprmask[2]; + _cpRegMask[3] = elf.ri_cprmask[3]; + } + + void merge(const MipsReginfo &info) { + _gpRegMask |= info._gpRegMask; + _cpRegMask[0] |= info._cpRegMask[0]; + _cpRegMask[1] |= info._cpRegMask[1]; + _cpRegMask[2] |= info._cpRegMask[2]; + _cpRegMask[3] |= info._cpRegMask[3]; + } +}; + +} // end namespace elf +} // end namespace lld + #endif diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h index 06142fd4c2a7..67ec6f3d756b 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h @@ -9,12 +9,59 @@ #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_SECTION_CHUNKS_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_SECTION_CHUNKS_H +#include "MipsReginfo.h" + namespace lld { namespace elf { template class MipsTargetLayout; class MipsLinkingContext; +/// \brief Handle Mips .reginfo section +template class MipsReginfoSection : public Section { +public: + MipsReginfoSection(const ELFLinkingContext &ctx, + MipsTargetLayout &targetLayout, + const MipsReginfo ®info) + : Section(ctx, ".reginfo", "MipsReginfo"), + _targetLayout(targetLayout) { + this->setOrder(MipsTargetLayout::ORDER_RO_NOTE); + this->_entSize = sizeof(Elf_RegInfo); + this->_fsize = sizeof(Elf_RegInfo); + this->_msize = sizeof(Elf_RegInfo); + this->_alignment = 4; + this->_type = SHT_MIPS_REGINFO; + this->_flags = SHF_ALLOC; + + memset(&_reginfo, 0, sizeof(_reginfo)); + _reginfo.ri_gprmask = reginfo._gpRegMask; + _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0]; + _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1]; + _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2]; + _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3]; + } + + void write(ELFWriter *writer, TargetLayout &layout, + llvm::FileOutputBuffer &buffer) override { + uint8_t *dest = buffer.getBufferStart() + this->fileOffset(); + std::memcpy(dest, &_reginfo, this->_fsize); + } + + void finalize() override { + const AtomLayout *gpAtom = _targetLayout.getGP(); + _reginfo.ri_gp_value = gpAtom ? gpAtom->_virtualAddr : 0;; + + if (this->_outputSection) + this->_outputSection->setType(this->_type); + } + +private: + typedef llvm::object::Elf_RegInfo Elf_RegInfo; + + Elf_RegInfo _reginfo; + MipsTargetLayout &_targetLayout; +}; + /// \brief Handle Mips GOT section template class MipsGOTSection : public AtomSection { public: diff --git a/lld/test/CMakeLists.txt b/lld/test/CMakeLists.txt index e29f5f4c5a90..dff9903f9256 100644 --- a/lld/test/CMakeLists.txt +++ b/lld/test/CMakeLists.txt @@ -20,7 +20,7 @@ configure_lit_site_cfg( ) set(LLD_TEST_DEPS - FileCheck not llvm-nm + FileCheck not llvm-ar llvm-nm lld llvm-config llvm-objdump llvm-readobj yaml2obj obj2yaml linker-script-test macho-dump llvm-mc llvm-nm ) diff --git a/lld/test/elf/Mips/base-address.test b/lld/test/elf/Mips/base-address.test index f55091f84c33..5f629a4b434f 100644 --- a/lld/test/elf/Mips/base-address.test +++ b/lld/test/elf/Mips/base-address.test @@ -77,16 +77,6 @@ Sections: Flags: [ SHF_WRITE, SHF_ALLOC ] AddressAlign: 0x04 Size: 0x00 - - Name: .reginfo - Type: SHT_MIPS_REGINFO - Flags: [ SHF_ALLOC ] - AddressAlign: 0x01 - Size: 0x18 - - Name: .MIPS.abiflags - Type: SHT_MIPS_ABIFLAGS - Flags: [ SHF_ALLOC ] - AddressAlign: 0x08 - Content: '000020010101000100000000000000000000000000000000' Symbols: Local: - Name: .text @@ -98,12 +88,6 @@ Symbols: - Name: .bss Type: STT_SECTION Section: .bss - - Name: .reginfo - Type: STT_SECTION - Section: .reginfo - - Name: .MIPS.abiflags - Type: STT_SECTION - Section: .MIPS.abiflags Global: - Name: main Section: .text diff --git a/lld/test/elf/Mips/dynlib-fileheader-micro.test b/lld/test/elf/Mips/dynlib-fileheader-micro.test index 139b3aa626c9..5572160b5aaf 100644 --- a/lld/test/elf/Mips/dynlib-fileheader-micro.test +++ b/lld/test/elf/Mips/dynlib-fileheader-micro.test @@ -64,11 +64,6 @@ Sections: Flags: [ SHF_WRITE, SHF_ALLOC ] AddressAlign: 0x04 Size: 0x00 - - Name: .reginfo - Type: SHT_MIPS_REGINFO - Flags: [ SHF_ALLOC ] - AddressAlign: 0x01 - Size: 0x18 - Name: .MIPS.abiflags Type: SHT_MIPS_ABIFLAGS Flags: [ SHF_ALLOC ] diff --git a/lld/test/elf/Mips/dynlib-fileheader.test b/lld/test/elf/Mips/dynlib-fileheader.test index 5dd9d6a64a71..426e07d05c7d 100644 --- a/lld/test/elf/Mips/dynlib-fileheader.test +++ b/lld/test/elf/Mips/dynlib-fileheader.test @@ -63,11 +63,6 @@ Sections: Flags: [ SHF_WRITE, SHF_ALLOC ] AddressAlign: 0x04 Size: 0x00 - - Name: .reginfo - Type: SHT_MIPS_REGINFO - Flags: [ SHF_ALLOC ] - AddressAlign: 0x01 - Size: 0x18 - Name: .MIPS.abiflags Type: SHT_MIPS_ABIFLAGS Flags: [ SHF_ALLOC ] diff --git a/lld/test/elf/Mips/mips-options-gp0.test b/lld/test/elf/Mips/mips-options-gp0.test index 339ab97253b6..6f4649121f86 100644 --- a/lld/test/elf/Mips/mips-options-gp0.test +++ b/lld/test/elf/Mips/mips-options-gp0.test @@ -1,12 +1,12 @@ # Check reading GP0 value from .MIPS.options section # # RUN: yaml2obj -format=elf %s > %t.o -# RUN: lld -flavor gnu -target mipsel -e G1 -shared -o %t.so %t.o +# RUN: lld -flavor gnu -target mips64el -e G1 -shared -o %t.so %t.o # RUN: llvm-readobj -symbols %t.so | FileCheck -check-prefix=SYM %s # RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=SEC %s # SYM: Name: L1 (1) -# SYM-NEXT: Value: 0xCC +# SYM-NEXT: Value: 0x134 # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Local (0x0) # SYM-NEXT: Type: Function (0x2) @@ -21,18 +21,17 @@ # SYM-NEXT: Other: 0 # SYM-NEXT: Section: Absolute (0xFFF1) -# 0xffff80dc == 0x0 (addend) + 0x00cc (L1) + 0x1000 (GP0) - 0x8ff0 (_gp) +# 0xffff8144 == 0x0 (addend) + 0x0134 (L1) + 0x1000 (GP0) - 0x8ff0 (_gp) # SEC: Contents of section .rodata: -# SEC-NEXT: 00d4 dc80ffff 00000000 00000000 00000000 ................ +# SEC-NEXT: 013c 4481ffff 00000000 00000000 00000000 !ELF FileHeader: - Class: ELFCLASS32 + Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_REL Machine: EM_MIPS - Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, - EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ] + Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64R2 ] Sections: - Name: .text Type: SHT_PROGBITS @@ -47,7 +46,7 @@ Sections: Size: 16 - Name: .rel.rodata - Type: SHT_REL + Type: SHT_RELA Link: .symtab Info: .rodata AddressAlign: 0x04 @@ -60,7 +59,7 @@ Sections: Type: SHT_MIPS_OPTIONS Flags: [ SHF_ALLOC ] AddressAlign: 0x01 - Content: "0128000000000000000000000000000000000000000000000000000000100000" + Content: "012800000000000000000000000000000000000000000000000000000000000000100000" Symbols: Local: diff --git a/lld/test/elf/Mips/reginfo-01.test b/lld/test/elf/Mips/reginfo-01.test new file mode 100644 index 000000000000..5076ef83470d --- /dev/null +++ b/lld/test/elf/Mips/reginfo-01.test @@ -0,0 +1,30 @@ +# Check that LLD does not write a .reginfo section if input +# object file does not contain such section. + +# RUN: yaml2obj -format=elf %s > %t.o +# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o +# RUN: llvm-readobj -s %t.so | FileCheck %s + +# CHECK-NOT: Name: .reginfo + +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 diff --git a/lld/test/elf/Mips/reginfo-02.test b/lld/test/elf/Mips/reginfo-02.test new file mode 100644 index 000000000000..1ab9391c7cea --- /dev/null +++ b/lld/test/elf/Mips/reginfo-02.test @@ -0,0 +1,74 @@ +# Check merging input .reginfo sections. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o +# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t1.o %t2.o +# RUN: llvm-objdump -s -t %t.so | FileCheck %s + +# CHECK: Contents of section .reginfo: +# CHECK-NEXT: 00b4 f0000001 e0000002 d0000003 c0000004 +# CHECK-NEXT: 00c4 b0000005 f08f0000 + +# CHECK: SYMBOL TABLE: +# CHECK: 00008ff0 g *ABS* 00000000 _gp + +# t1.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "F0000000E0000000D0000000C0000000B000000000100000" + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + +# t2.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "000000010000000200000003000000040000000500000100" + +Symbols: + Global: + - Name: T1 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 +... diff --git a/lld/test/elf/Mips/reginfo-03.test b/lld/test/elf/Mips/reginfo-03.test new file mode 100644 index 000000000000..0f5ea0e78cf3 --- /dev/null +++ b/lld/test/elf/Mips/reginfo-03.test @@ -0,0 +1,40 @@ +# Check handling a zero-filled input .reginfo section. + +# RUN: yaml2obj -format=elf %s > %t.o +# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o +# RUN: llvm-objdump -s -t %t.so | FileCheck %s + +# CHECK: Contents of section .reginfo: +# CHECK-NEXT: 00b4 00000000 00000000 00000000 00000000 +# CHECK-NEXT: 00c4 00000000 f08f0000 + +# CHECK: SYMBOL TABLE: +# CHECK: 00008ff0 g *ABS* 00000000 _gp + +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "000000000000000000000000000000000000000000000000" + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 diff --git a/lld/test/elf/Mips/reginfo-04.test b/lld/test/elf/Mips/reginfo-04.test new file mode 100644 index 000000000000..e3bd5f2d3178 --- /dev/null +++ b/lld/test/elf/Mips/reginfo-04.test @@ -0,0 +1,76 @@ +# Check that .reginfo sections from shared libraries do not affect +# output .reginfo section content. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t.so.o +# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.so.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t.exe.o +# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.so %t.exe.o +# RUN: llvm-objdump -s -t %t.exe | FileCheck %s + +# CHECK: Contents of section .reginfo: +# CHECK-NEXT: 400104 44444444 44444444 44444444 44444444 +# CHECK-NEXT: 400114 44444444 f08f4000 + +# CHECK: SYMBOL TABLE: +# CHECK: 00408ff0 g *ABS* 00000000 _gp + +# t.so.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "111111111111111111111111111111111111111100100000" + +Symbols: + Global: + - Name: T1 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + +# t.exe.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "444444444444444444444444444444444444444400000000" + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 +... diff --git a/lld/test/elf/Mips/reginfo-05.test b/lld/test/elf/Mips/reginfo-05.test new file mode 100644 index 000000000000..f4212705f800 --- /dev/null +++ b/lld/test/elf/Mips/reginfo-05.test @@ -0,0 +1,118 @@ +# Check that .reginfo section gets register usage mask from "used" files only. +# In this test case we take only t2.o from libreginfo.a and should not add +# register usage masks from t1.o to the output .reginfo section. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o +# RUN: llvm-ar q %T/libreginfo.a %t1.o %t2.o +# RUN: yaml2obj -format=elf -docnum 3 %s > %t3.o +# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t3.o -L%T -lreginfo +# RUN: llvm-objdump -s -t %t.exe | FileCheck %s + +# CHECK: Contents of section .reginfo: +# CHECK-NEXT: 400104 66666666 66666666 66666666 66666666 +# CHECK-NEXT: 400114 66666666 f08f4000 + +# CHECK: SYMBOL TABLE: +# CHECK: 00408ff0 g *ABS* 00000000 _gp + +# t1.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "111111111111111111111111111111111111111100000000" + +Symbols: + Global: + - Name: T1 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + +# t2.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "222222222222222222222222222222222222222200000000" + +Symbols: + Global: + - Name: T2 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + +# t3.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + +- Name: .rel.text + Type: SHT_REL + Info: .text + AddressAlign: 4 + Relocations: + - Offset: 0 + Symbol: T2 + Type: R_MIPS_32 + +- Name: .reginfo + Type: SHT_MIPS_REGINFO + Flags: [ SHF_ALLOC ] + AddressAlign: 4 + Content: "444444444444444444444444444444444444444400000000" + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + - Name: T2 +... diff --git a/lld/test/elf/Mips/rel-gprel16.test b/lld/test/elf/Mips/rel-gprel16.test index dc188ea6825a..84fc3ec5e97d 100644 --- a/lld/test/elf/Mips/rel-gprel16.test +++ b/lld/test/elf/Mips/rel-gprel16.test @@ -6,20 +6,20 @@ # RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=SEC %s # SYM: Name: L1 (1) -# SYM-NEXT: Value: 0xCC +# SYM-NEXT: Value: 0x104 # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Local (0x0) # SYM-NEXT: Type: Function (0x2) # SYM-NEXT: Other: 0 -# SYM-NEXT: Section: .text (0x4) +# SYM-NEXT: Section: .text (0x5) # SYM: Name: G1 (4) -# SYM-NEXT: Value: 0xD0 +# SYM-NEXT: Value: 0x108 # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Global (0x1) # SYM-NEXT: Type: Function (0x2) # SYM-NEXT: Other: 0 -# SYM-NEXT: Section: .text (0x4) +# SYM-NEXT: Section: .text (0x5) # SYM: Name: _gp (34) # SYM-NEXT: Value: 0x8FF0 @@ -29,9 +29,9 @@ # SYM-NEXT: Other: 0 # SYM-NEXT: Section: Absolute (0xFFF1) -# 0x160db == 0xffff (addend) + 0x00cc (L1) + 0x01f000 (GP0) - 0x8ff0 (_gp) +# 0x6113 == 0xffff (addend) + 0x0104 (L1) + 0x01f000 (GP0) - 0x8ff0 (_gp) # SEC: Contents of section .rodata: -# SEC-NEXT: 00d4 db600008 00000000 00000000 00000000 .`.............. +# SEC-NEXT: 010c 13610008 00000000 00000000 00000000 !ELF FileHeader: diff --git a/lld/test/elf/Mips/rel-gprel32.test b/lld/test/elf/Mips/rel-gprel32.test index 73ae6f161979..ced53f5f83ec 100644 --- a/lld/test/elf/Mips/rel-gprel32.test +++ b/lld/test/elf/Mips/rel-gprel32.test @@ -6,12 +6,12 @@ # RUN: llvm-objdump -s %t-exe | FileCheck -check-prefix=SEC %s # SYM: Name: $L1 (1) -# SYM-NEXT: Value: 0x400108 +# SYM-NEXT: Value: 0x400140 # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Local (0x0) # SYM-NEXT: Type: Function (0x2) # SYM-NEXT: Other: 0 -# SYM-NEXT: Section: .text (0x5) +# SYM-NEXT: Section: .text (0x6) # # SYM: Name: _gp (212) # SYM-NEXT: Value: 0x408FF0 @@ -21,10 +21,10 @@ # SYM-NEXT: Other: 0 # SYM-NEXT: Section: Absolute (0xFFF1) -# 0x08FF711B == 0x8000001 (addend) + 0x400108 ($L1) + +# 0x08ff7153 == 0x8000001 (addend) + 0x400140 ($L1) + # 0x1000002 (GP0) - 0x408FF0 (_gp) # SEC: Contents of section .rodata: -# SEC-NEXT: 400118 1b71ff08 00000000 00000000 00000000 .q.............. +# SEC-NEXT: 400150 5371ff08 00000000 00000000 00000000 !ELF FileHeader: -- 2.34.1