diff options
Diffstat (limited to 'lld')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h | 11 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp | 87 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h | 34 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFReader.h | 43 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h | 16 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h | 13 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp | 7 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h | 8 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-1.test | 132 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-2.test | 35 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-3.test | 133 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-4.test | 65 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-5.test | 42 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-6.test | 80 | ||||
| -rw-r--r-- | lld/test/elf/Mips/e-flags-merge-7.test | 42 |
16 files changed, 720 insertions, 29 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt index 7d3f4477897..1b38c6fb458 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt @@ -1,5 +1,6 @@ add_lld_library(lldMipsELFTarget MipsCtorsOrderPass.cpp + MipsELFFlagsMerger.cpp MipsLinkingContext.cpp MipsRelocationHandler.cpp MipsRelocationPass.cpp diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h index f62cf98f3c8..3a6df13b09d 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h @@ -24,7 +24,8 @@ template <class ELFT> class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> { public: MipsDynamicLibraryWriter(MipsLinkingContext &ctx, - MipsTargetLayout<ELFT> &layout); + MipsTargetLayout<ELFT> &layout, + MipsELFFlagsMerger &elfFlagsMerger); protected: // Add any runtime files and their atoms to the output @@ -51,9 +52,11 @@ private: template <class ELFT> MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter( - MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout) - : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout), - _mipsContext(ctx), _mipsTargetLayout(layout) {} + MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout, + MipsELFFlagsMerger &elfFlagsMerger) + : DynamicLibraryWriter<ELFT>(ctx, layout), + _writeHelper(ctx, layout, elfFlagsMerger), _mipsContext(ctx), + _mipsTargetLayout(layout) {} template <class ELFT> bool MipsDynamicLibraryWriter<ELFT>::createImplicitFiles( diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp new file mode 100644 index 00000000000..4db009dd84c --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp @@ -0,0 +1,87 @@ +//===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.cpp ------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MipsELFFlagsMerger.h" +#include "lld/Core/Error.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/raw_ostream.h" + +using namespace lld; +using namespace lld::elf; + +MipsELFFlagsMerger::MipsELFFlagsMerger() : _flags(0) {} + +uint32_t MipsELFFlagsMerger::getMergedELFFlags() const { return _flags; } + +std::error_code MipsELFFlagsMerger::merge(uint8_t newClass, uint32_t newFlags) { + // Reject 64-bit binaries. + if (newClass != llvm::ELF::ELFCLASS32) + return make_dynamic_error_code( + Twine("Bitness is incompatible with that of the selected target")); + + // We support the only ABI - O32 ... + uint32_t abi = newFlags & llvm::ELF::EF_MIPS_ABI; + if (abi != llvm::ELF::EF_MIPS_ABI_O32) + return make_dynamic_error_code(Twine("Unsupported ABI")); + + // ... and reduced set of architectures ... + uint32_t newArch = newFlags & llvm::ELF::EF_MIPS_ARCH; + switch (newArch) { + case llvm::ELF::EF_MIPS_ARCH_1: + case llvm::ELF::EF_MIPS_ARCH_2: + case llvm::ELF::EF_MIPS_ARCH_32: + case llvm::ELF::EF_MIPS_ARCH_32R2: + case llvm::ELF::EF_MIPS_ARCH_32R6: + break; + default: + return make_dynamic_error_code(Twine("Unsupported architecture")); + } + + // ... and still do not support MIPS-16 extension. + if (newFlags & llvm::ELF::EF_MIPS_ARCH_ASE_M16) + return make_dynamic_error_code(Twine("Unsupported extension: MIPS16")); + + std::lock_guard<std::mutex> lock(_mutex); + + // If the old set of flags is empty, use the new one as a result. + if (!_flags) { + _flags = newFlags; + return std::error_code(); + } + + // Check PIC / CPIC flags compatibility. + uint32_t newPic = + newFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC); + uint32_t oldPic = _flags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC); + + if ((newPic != 0) != (oldPic != 0)) + llvm::errs() << "lld warning: linking abicalls and non-abicalls files\n"; + + if (newPic != 0) + _flags |= llvm::ELF::EF_MIPS_CPIC; + if (!(newPic & llvm::ELF::EF_MIPS_PIC)) + _flags &= ~llvm::ELF::EF_MIPS_PIC; + + // Check mixing -mnan=2008 / -mnan=legacy modules. + if ((newFlags & llvm::ELF::EF_MIPS_NAN2008) != + (_flags & llvm::ELF::EF_MIPS_NAN2008)) + return make_dynamic_error_code( + Twine("Linking -mnan=2008 and -mnan=legacy modules")); + + // Set the "largest" ISA. + uint32_t oldArch = _flags & llvm::ELF::EF_MIPS_ARCH; + _flags |= std::max(newArch, oldArch); + + _flags |= newFlags & llvm::ELF::EF_MIPS_NOREORDER; + _flags |= newFlags & llvm::ELF::EF_MIPS_MICROMIPS; + _flags |= newFlags & llvm::ELF::EF_MIPS_NAN2008; + + return std::error_code(); +} diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h new file mode 100644 index 00000000000..bed63fa2616 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h @@ -0,0 +1,34 @@ +//===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.h --------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FLAGS_MERGER_H +#define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FLAGS_MERGER_H + +#include <mutex> + +namespace lld { +namespace elf { + +class MipsELFFlagsMerger { +public: + MipsELFFlagsMerger(); + + uint32_t getMergedELFFlags() const; + + /// \brief Merge saved ELF header flags and the new set of flags. + std::error_code merge(uint8_t newClass, uint32_t newFlags); + +private: + std::mutex _mutex; + uint32_t _flags; +}; + +} // namespace elf +} // namespace lld + +#endif diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFReader.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFReader.h index ef847f44c37..7ccc8124061 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFReader.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFReader.h @@ -11,6 +11,7 @@ #include "ELFReader.h" #include "MipsELFFile.h" +#include "MipsELFFlagsMerger.h" namespace lld { namespace elf { @@ -39,18 +40,48 @@ struct MipsDynamicFileCreateELFTraits { class MipsELFObjectReader : public ELFObjectReader<Mips32ElELFType, MipsELFFileCreateTraits> { + typedef ELFObjectReader<Mips32ElELFType, MipsELFFileCreateTraits> + BaseReaderType; + public: - MipsELFObjectReader(bool atomizeStrings) - : ELFObjectReader<Mips32ElELFType, MipsELFFileCreateTraits>( - atomizeStrings, llvm::ELF::EM_MIPS) {} + MipsELFObjectReader(MipsELFFlagsMerger &flagMerger, bool atomizeStrings) + : BaseReaderType(atomizeStrings, llvm::ELF::EM_MIPS), + _flagMerger(flagMerger) {} + + std::error_code + parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry ®istry, + std::vector<std::unique_ptr<File>> &result) const override { + auto &hdr = *elfHeader(*mb); + if (std::error_code ec = _flagMerger.merge(hdr.getFileClass(), hdr.e_flags)) + return ec; + return BaseReaderType::parseFile(mb, registry, result); + } + +private: + MipsELFFlagsMerger &_flagMerger; }; class MipsELFDSOReader : public ELFDSOReader<Mips32ElELFType, MipsDynamicFileCreateELFTraits> { + typedef ELFDSOReader<Mips32ElELFType, MipsDynamicFileCreateELFTraits> + BaseReaderType; + public: - MipsELFDSOReader(bool useUndefines) - : ELFDSOReader<Mips32ElELFType, MipsDynamicFileCreateELFTraits>( - useUndefines, llvm::ELF::EM_MIPS) {} + MipsELFDSOReader(MipsELFFlagsMerger &flagMerger, bool useUndefines) + : BaseReaderType(useUndefines, llvm::ELF::EM_MIPS), + _flagMerger(flagMerger) {} + + std::error_code + parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry ®istry, + std::vector<std::unique_ptr<File>> &result) const override { + auto &hdr = *elfHeader(*mb); + if (std::error_code ec = _flagMerger.merge(hdr.getFileClass(), hdr.e_flags)) + return ec; + return BaseReaderType::parseFile(mb, registry, result); + } + +private: + MipsELFFlagsMerger &_flagMerger; }; } // namespace elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h index 3b8a397b9c3..f4c4d0817dc 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h @@ -9,6 +9,7 @@ #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H +#include "MipsELFFlagsMerger.h" #include "MipsLinkingContext.h" #include "OutputELFWriter.h" @@ -21,8 +22,10 @@ template <class ELFT> class MipsTargetLayout; template <typename ELFT> class MipsELFWriter { public: - MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout) - : _ctx(ctx), _targetLayout(targetLayout) {} + MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout, + MipsELFFlagsMerger &elfFlagsMerger) + : _ctx(ctx), _targetLayout(targetLayout), + _elfFlagsMerger(elfFlagsMerger) {} void setELFHeader(ELFHeader<ELFT> &elfHeader) { elfHeader.e_version(1); @@ -33,13 +36,7 @@ public: else elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0); - // FIXME (simon): Read elf flags from all inputs, check compatibility, - // merge them and write result here. - uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 | - llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2; - if (_ctx.getOutputELFType() == llvm::ELF::ET_DYN) - flags |= EF_MIPS_PIC; - elfHeader.e_flags(flags); + elfHeader.e_flags(_elfFlagsMerger.getMergedELFFlags()); } void finalizeMipsRuntimeAtomValues() { @@ -74,6 +71,7 @@ public: private: MipsLinkingContext &_ctx; MipsTargetLayout<ELFT> &_targetLayout; + MipsELFFlagsMerger &_elfFlagsMerger; void setAtomValue(StringRef name, uint64_t value) { auto atom = _targetLayout.findAbsoluteAtom(name); diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h index 85b79d26aa6..0e351b46b2a 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h @@ -22,7 +22,8 @@ template <typename ELFT> class MipsTargetLayout; template <class ELFT> class MipsExecutableWriter : public ExecutableWriter<ELFT> { public: - MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout); + MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout, + MipsELFFlagsMerger &elfFlagsMerger); protected: void buildDynamicSymbolTable(const File &file) override; @@ -50,10 +51,12 @@ private: }; template <class ELFT> -MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx, - MipsTargetLayout<ELFT> &layout) - : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout), - _mipsContext(ctx), _mipsTargetLayout(layout) {} +MipsExecutableWriter<ELFT>::MipsExecutableWriter( + MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout, + MipsELFFlagsMerger &elfFlagsMerger) + : ExecutableWriter<ELFT>(ctx, layout), + _writeHelper(ctx, layout, elfFlagsMerger), _mipsContext(ctx), + _mipsTargetLayout(layout) {} template <class ELFT> void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp index 45415ee0820..caec0c4a7e4 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp @@ -27,11 +27,12 @@ MipsTargetHandler::MipsTargetHandler(MipsLinkingContext &ctx) std::unique_ptr<Writer> MipsTargetHandler::getWriter() { switch (_ctx.getOutputELFType()) { case llvm::ELF::ET_EXEC: - return std::unique_ptr<Writer>( - new MipsExecutableWriter<Mips32ElELFType>(_ctx, *_targetLayout)); + return std::unique_ptr<Writer>(new MipsExecutableWriter<Mips32ElELFType>( + _ctx, *_targetLayout, _elfFlagsMerger)); case llvm::ELF::ET_DYN: return std::unique_ptr<Writer>( - new MipsDynamicLibraryWriter<Mips32ElELFType>(_ctx, *_targetLayout)); + new MipsDynamicLibraryWriter<Mips32ElELFType>(_ctx, *_targetLayout, + _elfFlagsMerger)); case llvm::ELF::ET_REL: llvm_unreachable("TODO: support -r mode"); default: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h index a34d6d0d065..29b4cd6afc8 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h @@ -10,6 +10,7 @@ #define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H #include "DefaultTargetHandler.h" +#include "MipsELFFlagsMerger.h" #include "MipsELFReader.h" #include "MipsLinkingContext.h" #include "MipsRelocationHandler.h" @@ -108,11 +109,13 @@ public: } std::unique_ptr<Reader> getObjReader(bool atomizeStrings) override { - return std::unique_ptr<Reader>(new MipsELFObjectReader(atomizeStrings)); + return std::unique_ptr<Reader>( + new MipsELFObjectReader(_elfFlagsMerger, atomizeStrings)); } std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) override { - return std::unique_ptr<Reader>(new MipsELFDSOReader(useShlibUndefines)); + return std::unique_ptr<Reader>( + new MipsELFDSOReader(_elfFlagsMerger, useShlibUndefines)); } const MipsTargetRelocationHandler &getRelocationHandler() const override { @@ -126,6 +129,7 @@ public: private: static const Registry::KindStrings kindStrings[]; MipsLinkingContext &_ctx; + MipsELFFlagsMerger _elfFlagsMerger; std::unique_ptr<MipsRuntimeFile<Mips32ElELFType>> _runtimeFile; std::unique_ptr<MipsTargetLayout<Mips32ElELFType>> _targetLayout; std::unique_ptr<MipsTargetRelocationHandler> _relocationHandler; diff --git a/lld/test/elf/Mips/e-flags-merge-1.test b/lld/test/elf/Mips/e-flags-merge-1.test new file mode 100644 index 00000000000..f3308daeed4 --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-1.test @@ -0,0 +1,132 @@ +# Check that the linker shows an error when object file has missed +# or unsupported ABI and ARCH flags or unsupported ASE flags. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-no-abi.o +# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-no-abi.o 2>&1 | \ +# RUN: FileCheck -check-prefix=INVALID-ABI %s + +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-arch3.o +# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-arch3.o 2>&1 | \ +# RUN: FileCheck -check-prefix=INVALID-ARCH %s + +# RUN: yaml2obj -format=elf -docnum 3 %s > %t-arch4.o +# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-arch4.o 2>&1 | \ +# RUN: FileCheck -check-prefix=INVALID-ARCH %s + +# RUN: yaml2obj -format=elf -docnum 4 %s > %t-arch64.o +# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-arch64.o 2>&1 | \ +# RUN: FileCheck -check-prefix=INVALID-ARCH %s + +# RUN: yaml2obj -format=elf -docnum 5 %s > %t-mips16.o +# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-mips16.o 2>&1 | \ +# RUN: FileCheck -check-prefix=MIPS16 %s + +# INVALID-ABI: Unsupported ABI +# INVALID-ARCH: Unsupported architecture +# MIPS16: Unsupported extension: MIPS16 + +# no-abi.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T + Section: .text + +# arch3.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_3] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T + Section: .text + +# arch4.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_4] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T + Section: .text + +# arch64.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_64] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T + Section: .text + +# mips16.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_ARCH_ASE_M16] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T + Section: .text +... diff --git a/lld/test/elf/Mips/e-flags-merge-2.test b/lld/test/elf/Mips/e-flags-merge-2.test new file mode 100644 index 00000000000..41d4a0b0c45 --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-2.test @@ -0,0 +1,35 @@ +# Check that the linker copies ELF header flags from the single input object +# file to the generated executable + +# RUN: yaml2obj -format=elf %s > %t.o +# RUN: lld -flavor gnu -target mipsel -e T -o %t.exe %t.o +# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s + +# CHECK: Flags [ (0x52001001) +# CHECK-NEXT: EF_MIPS_ABI_O32 (0x1000) +# CHECK-NEXT: EF_MIPS_ARCH_32 (0x50000000) +# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000) +# CHECK-NEXT: EF_MIPS_NOREORDER (0x1) +# CHECK-NEXT: ] + +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, + EF_MIPS_NOREORDER, EF_MIPS_MICROMIPS] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T + Section: .text +... diff --git a/lld/test/elf/Mips/e-flags-merge-3.test b/lld/test/elf/Mips/e-flags-merge-3.test new file mode 100644 index 00000000000..4551eb1d7fa --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-3.test @@ -0,0 +1,133 @@ +# Check PIC/CPIC flags merging in case of multiple input objects. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-none.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-cpic.o +# RUN: yaml2obj -format=elf -docnum 3 %s > %t-pic.o +# RUN: yaml2obj -format=elf -docnum 4 %s > %t-both.o + +# RUN: lld -flavor gnu -target mipsel -e T1 -o %t-abi1.exe \ +# RUN: %t-none.o %t-pic.o 2>&1 | FileCheck -check-prefix=ABI-CALLS-WARN %s +# RUN: llvm-readobj -file-headers %t-abi1.exe \ +# RUN: | FileCheck -check-prefix=ABI-CALLS1 %s + +# RUN: lld -flavor gnu -target mipsel -e T1 -o %t-abi2.exe \ +# RUN: %t-cpic.o %t-none.o 2>&1 | FileCheck -check-prefix=ABI-CALLS-WARN %s +# RUN: llvm-readobj -file-headers %t-abi2.exe \ +# RUN: | FileCheck -check-prefix=ABI-CALLS2 %s + +# RUN: lld -flavor gnu -target mipsel -e T2 -o %t-cpic.exe %t-cpic.o %t-pic.o +# RUN: llvm-readobj -file-headers %t-cpic.exe | FileCheck -check-prefix=CPIC %s + +# RUN: lld -flavor gnu -target mipsel -e T3 -o %t-both.exe %t-pic.o %t-both.o +# RUN: llvm-readobj -file-headers %t-both.exe | FileCheck -check-prefix=BOTH %s + +# ABI-CALLS-WARN: lld warning: linking abicalls and non-abicalls files + +# ABI-CALLS1: Flags [ (0x50001000) +# ABI-CALLS1-NEXT: EF_MIPS_ABI_O32 (0x1000) +# ABI-CALLS1-NEXT: EF_MIPS_ARCH_32 (0x50000000) +# ABI-CALLS1-NEXT: ] + +# ABI-CALLS2: Flags [ (0x50001004) +# ABI-CALLS2-NEXT: EF_MIPS_ABI_O32 (0x1000) +# ABI-CALLS2-NEXT: EF_MIPS_ARCH_32 (0x50000000) +# ABI-CALLS2-NEXT: EF_MIPS_CPIC (0x4) +# ABI-CALLS2-NEXT: ] + +# CPIC: Flags [ (0x50001004) +# CPIC-NEXT: EF_MIPS_ABI_O32 (0x1000) +# CPIC-NEXT: EF_MIPS_ARCH_32 (0x50000000) +# CPIC-NEXT: EF_MIPS_CPIC (0x4) +# CPIC-NEXT: ] + +# BOTH: Flags [ (0x50001006) +# BOTH-NEXT: EF_MIPS_ABI_O32 (0x1000) +# BOTH-NEXT: EF_MIPS_ARCH_32 (0x50000000) +# BOTH-NEXT: EF_MIPS_CPIC (0x4) +# BOTH-NEXT: EF_MIPS_PIC (0x2) +# BOTH-NEXT: ] + +# none.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T1 + Section: .text + +# cpic.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T2 + Section: .text + +# pic.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_PIC] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T3 + Section: .text + +# both.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC, EF_MIPS_PIC] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +Symbols: + Global: + - Name: T4 + Section: .text +... diff --git a/lld/test/elf/Mips/e-flags-merge-4.test b/lld/test/elf/Mips/e-flags-merge-4.test new file mode 100644 index 00000000000..096b04d676e --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-4.test @@ -0,0 +1,65 @@ +# Check ELF flags merging. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-none.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-noreorder.o +# RUN: yaml2obj -format=elf -docnum 3 %s > %t-micro.o + +# RUN: lld -flavor gnu -target mipsel -shared -o %t.so \ +# RUN: %t-none.o %t-noreorder.o %t-micro.o +# RUN: llvm-readobj -file-headers %t.so | FileCheck %s + +# CHECK: Flags [ (0x52001001) +# CHECK-NEXT: EF_MIPS_ABI_O32 (0x1000) +# CHECK-NEXT: EF_MIPS_ARCH_32 (0x50000000) +# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000) +# CHECK-NEXT: EF_MIPS_NOREORDER (0x1) +# CHECK-NEXT: ] + +# none.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# noreorder.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_NOREORDER] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# micro.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_MICROMIPS] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 +... diff --git a/lld/test/elf/Mips/e-flags-merge-5.test b/lld/test/elf/Mips/e-flags-merge-5.test new file mode 100644 index 00000000000..3b5b397ab78 --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-5.test @@ -0,0 +1,42 @@ +# Check that LLD does not allow to mix 32 and 64-bit MIPS object files. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-32.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-64.o + +# RUN: not lld -flavor gnu -target mipsel -shared -o %t.so \ +# RUN: %t-32.o %t-64.o 2>&1 | FileCheck %s + +# CHECK: Bitness is incompatible with that of the selected target + +# 32.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# 64.o +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ARCH_64] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 +... diff --git a/lld/test/elf/Mips/e-flags-merge-6.test b/lld/test/elf/Mips/e-flags-merge-6.test new file mode 100644 index 00000000000..759c8b63c97 --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-6.test @@ -0,0 +1,80 @@ +# Check selecting ELF header ARCH flag. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-m1.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-m2.o +# RUN: yaml2obj -format=elf -docnum 3 %s > %t-m32.o +# RUN: yaml2obj -format=elf -docnum 4 %s > %t-m32r2.o + +# RUN: lld -flavor gnu -target mipsel -shared -o %t.so \ +# RUN: %t-m32.o %t-m2.o %t-m32r2.o %t-m1.o +# RUN: llvm-readobj -file-headers %t.so | FileCheck %s + +# CHECK: Flags [ (0x70001000) +# CHECK-NEXT: EF_MIPS_ABI_O32 (0x1000) +# CHECK-NEXT: EF_MIPS_ARCH_32R2 (0x70000000) +# CHECK-NEXT: ] + +# m1.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_1] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# m2.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_2] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# m32.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# m32r2.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 +... diff --git a/lld/test/elf/Mips/e-flags-merge-7.test b/lld/test/elf/Mips/e-flags-merge-7.test new file mode 100644 index 00000000000..7e114ff968f --- /dev/null +++ b/lld/test/elf/Mips/e-flags-merge-7.test @@ -0,0 +1,42 @@ +# Check that LLD does not allow to mix nan2008 and legacy MIPS object files. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-2008.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-legacy.o + +# RUN: not lld -flavor gnu -target mipsel -shared -o %t.so \ +# RUN: %t-2008.o %t-legacy.o 2>&1 | FileCheck %s + +# CHECK: Linking -mnan=2008 and -mnan=legacy modules + +# 2008.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_NAN2008] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 + +# legacy.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x04 +... |

