forked from OSchip/llvm-project
[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:
parent
4c6bd6a10d
commit
b915d07a8e
|
@ -1,5 +1,6 @@
|
|||
add_lld_library(lldMipsELFTarget
|
||||
MipsCtorsOrderPass.cpp
|
||||
MipsELFFlagsMerger.cpp
|
||||
MipsLinkingContext.cpp
|
||||
MipsRelocationHandler.cpp
|
||||
MipsRelocationPass.cpp
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
Loading…
Reference in New Issue