diff options
19 files changed, 491 insertions, 49 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h index 034b57ca7c3..a72a467b808 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<std::unique_ptr<File>> &) override; void finalizeDefaultAtomValues() override; + void createDefaultSections() override; std::error_code setELFHeader() override { DynamicLibraryWriter<ELFT>::setELFHeader(); @@ -46,6 +48,7 @@ protected: private: MipsELFWriter<ELFT> _writeHelper; MipsTargetLayout<ELFT> &_targetLayout; + unique_bump_ptr<Section<ELFT>> _reginfo; }; template <class ELFT> @@ -70,6 +73,19 @@ void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() { } template <class ELFT> +void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() { + DynamicLibraryWriter<ELFT>::createDefaultSections(); + const auto &mask = + static_cast<const MipsLinkingContext &>(this->_ctx).getMergeReginfoMask(); + if (!ELFT::Is64Bits && mask.hasValue()) { + _reginfo = unique_bump_ptr<Section<ELFT>>( + new (this->_alloc) + MipsReginfoSection<ELFT>(this->_ctx, _targetLayout, *mask)); + this->_layout.addSection(_reginfo.get()); + } +} + +template <class ELFT> unique_bump_ptr<SymbolTable<ELFT>> MipsDynamicLibraryWriter<ELFT>::createSymbolTable() { return unique_bump_ptr<SymbolTable<ELFT>>( diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h index 7376fb5f2cf..92d1165595e 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<ELFT> Elf_RegInfo; typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options; + auto &ctx = static_cast<MipsLinkingContext &>(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<const Elf_Mips_Options *>(raw.data()); + const auto *opt = + reinterpret_cast<const Elf_Mips_Options *>(raw.data()); if (opt->kind == ODK_REGINFO) { - _gp0 = reinterpret_cast<const Elf_RegInfo *>(opt + 1)->ri_gp_value; + const auto *regInfo = reinterpret_cast<const Elf_RegInfo *>(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<const Elf_RegInfo *>(raw.data())->ri_gp_value; + const auto *regInfo = reinterpret_cast<const Elf_RegInfo *>(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 3927d69e6be..61e2eedc539 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<std::unique_ptr<File>> &) override; void finalizeDefaultAtomValues() override; + void createDefaultSections() override; std::error_code setELFHeader() override; unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override; @@ -40,6 +41,7 @@ protected: private: MipsELFWriter<ELFT> _writeHelper; MipsTargetLayout<ELFT> &_targetLayout; + unique_bump_ptr<Section<ELFT>> _reginfo; }; template <class ELFT> @@ -122,6 +124,18 @@ void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() { _writeHelper.finalizeMipsRuntimeAtomValues(); } +template <class ELFT> void MipsExecutableWriter<ELFT>::createDefaultSections() { + ExecutableWriter<ELFT>::createDefaultSections(); + const auto &mask = + static_cast<const MipsLinkingContext &>(this->_ctx).getMergeReginfoMask(); + if (!ELFT::Is64Bits && mask.hasValue()) { + _reginfo = unique_bump_ptr<Section<ELFT>>( + new (this->_alloc) + MipsReginfoSection<ELFT>(this->_ctx, _targetLayout, *mask)); + this->_layout.addSection(_reginfo.get()); + } +} + template <class ELFT> unique_bump_ptr<SymbolTable<ELFT>> MipsExecutableWriter<ELFT>::createSymbolTable() { diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index ea91fcfd6de..fcbd72471ee 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<MipsReginfo> & +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 f6679706866..d77ba25c965 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<MipsReginfo> &getMergeReginfoMask() const; + void registerRelocationNames(Registry &r) override; // ELFLinkingContext @@ -62,6 +67,7 @@ public: private: MipsELFFlagsMerger _flagsMerger; + llvm::Optional<MipsReginfo> _reginfoMask; }; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h b/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h index 01552a293de..83ccaa5e1a6 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsReginfo.h @@ -47,4 +47,33 @@ template <class ELFT> 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 <class ElfReginfo> 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 06142fd4c2a..67ec6f3d756 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 <typename ELFT> class MipsTargetLayout; class MipsLinkingContext; +/// \brief Handle Mips .reginfo section +template <class ELFT> class MipsReginfoSection : public Section<ELFT> { +public: + MipsReginfoSection(const ELFLinkingContext &ctx, + MipsTargetLayout<ELFT> &targetLayout, + const MipsReginfo ®info) + : Section<ELFT>(ctx, ".reginfo", "MipsReginfo"), + _targetLayout(targetLayout) { + this->setOrder(MipsTargetLayout<ELFT>::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<ELFT> &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<ELFT> Elf_RegInfo; + + Elf_RegInfo _reginfo; + MipsTargetLayout<ELFT> &_targetLayout; +}; + /// \brief Handle Mips GOT section template <class ELFT> class MipsGOTSection : public AtomSection<ELFT> { public: diff --git a/lld/test/CMakeLists.txt b/lld/test/CMakeLists.txt index e29f5f4c5a9..dff9903f925 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 f55091f84c3..5f629a4b434 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 139b3aa626c..5572160b5aa 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 5dd9d6a64a7..426e07d05c7 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 339ab97253b..6f4649121f8 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 00000000000..5076ef83470 --- /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 00000000000..1ab9391c7ce --- /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 00000000000..0f5ea0e78cf --- /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 00000000000..e3bd5f2d317 --- /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 00000000000..f4212705f80 --- /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 dc188ea6825..84fc3ec5e97 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 73ae6f16197..ced53f5f83e 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: |