[Mips] Check ELF flags to prevent linking of incompatible files

1. The path checks ELF header flags to prevent linking of incompatible files.
   For example we do not allow to link files with different ABI, -mnan
   flags, some combination of target CPU etc.
2. The patch merge ELF header flags from input object files to put their
   combination to the generated file. For example, if some input files
   have EF_MIPS_NOREORDER flag we need to put this flag to the output
   file header.

I use the `parseFile()` (not `canParse()`) method because in case of
recognition of incorrect input flags combination we should show detailed
error message and stop the linking process and should not try to use
another `Reader`.

llvm-svn: 221439
This commit is contained in:
Simon Atanasyan 2014-11-06 05:53:10 +00:00
parent 4c6bd6a10d
commit b915d07a8e
16 changed files with 720 additions and 29 deletions

View File

@ -1,5 +1,6 @@
add_lld_library(lldMipsELFTarget
MipsCtorsOrderPass.cpp
MipsELFFlagsMerger.cpp
MipsLinkingContext.cpp
MipsRelocationHandler.cpp
MipsRelocationPass.cpp

View File

@ -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(

View File

@ -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();
}

View File

@ -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

View File

@ -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 &registry,
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 &registry,
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

View File

@ -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);

View File

@ -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) {

View File

@ -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:

View File

@ -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;

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...