[Mips] Teach LLD to recognize one more MIPS target triple - mips64el

This is initial patch to support MIPS64 object files linking.
The patch just makes some classes more generalized, and rejects
attempts to interlinking O32 and N64 ABI object files.

I try to reuse the current MIPS target related classes as much as
possible because O32 and N64 MIPS ABI are tightly related and share
almost the same set of relocations, GOT, flags etc.

llvm-svn: 227058
This commit is contained in:
Simon Atanasyan 2015-01-25 19:15:35 +00:00
parent 07e8a406d6
commit 0712650742
24 changed files with 944 additions and 78 deletions

View File

@ -186,8 +186,11 @@ getArchType(const llvm::Triple &triple, StringRef value) {
return llvm::Triple::x86_64;
return llvm::None;
case llvm::Triple::mipsel:
case llvm::Triple::mips64el:
if (value == "elf32ltsmip")
return llvm::Triple::mipsel;
if (value == "elf64ltsmip")
return llvm::Triple::mips64el;
return llvm::None;
case llvm::Triple::aarch64:
if (value == "aarch64linux")

View File

@ -80,6 +80,7 @@ uint16_t ELFLinkingContext::getOutputMachine() const {
case llvm::Triple::hexagon:
return llvm::ELF::EM_HEXAGON;
case llvm::Triple::mipsel:
case llvm::Triple::mips64el:
return llvm::ELF::EM_MIPS;
case llvm::Triple::ppc:
return llvm::ELF::EM_PPC;

View File

@ -57,19 +57,22 @@ static bool matchMipsISA(unsigned base, unsigned ext) {
return false;
}
MipsELFFlagsMerger::MipsELFFlagsMerger() : _flags(0) {}
MipsELFFlagsMerger::MipsELFFlagsMerger(bool is64Bits)
: _is64Bit(is64Bits), _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 != ELFCLASS32)
// Check bitness.
if (_is64Bit != (newClass == ELFCLASS64))
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 & EF_MIPS_ABI;
if (abi != EF_MIPS_ABI_O32)
// We support two ABI: O32 and N64. The last one does not have
// the corresponding ELF flag.
uint32_t inAbi = newFlags & EF_MIPS_ABI;
uint32_t supportedAbi = _is64Bit ? 0 : EF_MIPS_ABI_O32;
if (inAbi != supportedAbi)
return make_dynamic_error_code(Twine("Unsupported ABI"));
// ... and reduced set of architectures ...

View File

@ -17,7 +17,7 @@ namespace elf {
class MipsELFFlagsMerger {
public:
MipsELFFlagsMerger();
MipsELFFlagsMerger(bool is64Bits);
uint32_t getMergedELFFlags() const;
@ -25,6 +25,7 @@ public:
std::error_code merge(uint8_t newClass, uint32_t newFlags);
private:
const bool _is64Bit;
std::mutex _mutex;
uint32_t _flags;
};

View File

@ -18,15 +18,29 @@ using namespace lld::elf;
std::unique_ptr<ELFLinkingContext>
MipsLinkingContext::create(llvm::Triple triple) {
if (triple.getArch() == llvm::Triple::mipsel)
return std::unique_ptr<ELFLinkingContext>(
new MipsLinkingContext(triple));
if (triple.getArch() == llvm::Triple::mipsel ||
triple.getArch() == llvm::Triple::mips64el)
return std::unique_ptr<ELFLinkingContext>(new MipsLinkingContext(triple));
return nullptr;
}
typedef std::unique_ptr<TargetHandlerBase> TargetHandlerBasePtr;
static TargetHandlerBasePtr createTarget(llvm::Triple triple,
MipsLinkingContext &ctx) {
switch (triple.getArch()) {
case llvm::Triple::mipsel:
return TargetHandlerBasePtr(new MipsTargetHandler<Mips32ELType>(ctx));
case llvm::Triple::mips64el:
return TargetHandlerBasePtr(new MipsTargetHandler<Mips64ELType>(ctx));
default:
llvm_unreachable("Unhandled arch");
}
}
MipsLinkingContext::MipsLinkingContext(llvm::Triple triple)
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new MipsTargetHandler(*this))) {}
: ELFLinkingContext(triple, createTarget(triple, *this)),
_flagsMerger(triple.isArch64Bit()) {}
uint32_t MipsLinkingContext::getMergedELFFlags() const {
return _flagsMerger.getMergedELFFlags();
@ -38,7 +52,7 @@ MipsELFFlagsMerger &MipsLinkingContext::getELFFlagsMerger() {
uint64_t MipsLinkingContext::getBaseAddress() const {
if (_baseAddress == 0 && getOutputELFType() == llvm::ELF::ET_EXEC)
return 0x400000;
return getTriple().isArch64Bit() ? 0x120000000 : 0x400000;
return _baseAddress;
}
@ -49,7 +63,7 @@ StringRef MipsLinkingContext::entrySymbolName() const {
}
StringRef MipsLinkingContext::getDefaultInterpreter() const {
return "/lib/ld.so.1";
return getTriple().isArch64Bit() ? "/lib64/ld.so.1" : "/lib/ld.so.1";
}
void MipsLinkingContext::addPasses(PassManager &pm) {

View File

@ -33,9 +33,8 @@ enum {
LLD_R_MICROMIPS_GLOBAL_26_S1 = 1030,
};
typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType;
template <class ELFType> class MipsTargetLayout;
typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ELType;
typedef llvm::object::ELFType<llvm::support::little, 2, true> Mips64ELType;
class MipsLinkingContext final : public ELFLinkingContext {
public:

View File

@ -188,17 +188,38 @@ static uint32_t microShuffle(uint32_t ins) {
return ((ins & 0xffff) << 16) | ((ins & 0xffff0000) >> 16);
}
std::error_code MipsTargetRelocationHandler::applyRelocation(
namespace {
template <class ELFT> class RelocationHandler : public TargetRelocationHandler {
public:
RelocationHandler(MipsLinkingContext &ctx) : _ctx(ctx) {}
std::error_code applyRelocation(ELFWriter &writer,
llvm::FileOutputBuffer &buf,
const lld::AtomLayout &atom,
const Reference &ref) const override;
private:
MipsLinkingContext &_ctx;
MipsTargetLayout<ELFT> &getTargetLayout() const {
return static_cast<MipsTargetLayout<ELFT> &>(
_ctx.getTargetHandler<ELFT>().getTargetLayout());
}
};
template <class ELFT>
std::error_code RelocationHandler<ELFT>::applyRelocation(
ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
const Reference &ref) const {
if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
return std::error_code();
assert(ref.kindArch() == Reference::KindArch::Mips);
AtomLayout *gpAtom = _mipsTargetLayout.getGP();
AtomLayout *gpAtom = getTargetLayout().getGP();
uint64_t gpAddr = gpAtom ? gpAtom->_virtualAddr : 0;
AtomLayout *gpDispAtom = _mipsTargetLayout.getGPDisp();
AtomLayout *gpDispAtom = getTargetLayout().getGPDisp();
bool isGpDisp = gpDispAtom && ref.target() == gpDispAtom->_atom;
uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
@ -349,3 +370,19 @@ std::error_code MipsTargetRelocationHandler::applyRelocation(
endian::write<uint32_t, little, 2>(location, ins);
return std::error_code();
}
} // end anon namespace
template <>
std::unique_ptr<TargetRelocationHandler>
lld::elf::createMipsRelocationHandler<Mips32ELType>(MipsLinkingContext &ctx) {
return std::unique_ptr<TargetRelocationHandler>(
new RelocationHandler<Mips32ELType>(ctx));
}
template <>
std::unique_ptr<TargetRelocationHandler>
lld::elf::createMipsRelocationHandler<Mips64ELType>(MipsLinkingContext &ctx) {
return std::unique_ptr<TargetRelocationHandler>(
new RelocationHandler<Mips64ELType>(ctx));
}

View File

@ -9,25 +9,15 @@
#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_RELOCATION_HANDLER_H
#define LLD_READER_WRITER_ELF_MIPS_MIPS_RELOCATION_HANDLER_H
#include "MipsLinkingContext.h"
namespace lld {
namespace elf {
class MipsTargetHandler;
class MipsLinkingContext;
class TargetRelocationHandler;
class MipsTargetRelocationHandler final : public TargetRelocationHandler {
public:
MipsTargetRelocationHandler(MipsTargetLayout<Mips32ElELFType> &layout)
: _mipsTargetLayout(layout) {}
std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
const Reference &) const override;
private:
MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
};
template <class ELFT>
std::unique_ptr<TargetRelocationHandler>
createMipsRelocationHandler(MipsLinkingContext &ctx);
} // elf
} // lld

View File

@ -949,12 +949,23 @@ RelocationPass<ELFT>::getObjectEntry(const SharedLibraryAtom *a) {
} // end anon namespace
static std::unique_ptr<Pass> createPass(MipsLinkingContext &ctx) {
switch (ctx.getTriple().getArch()) {
case llvm::Triple::mipsel:
return std::unique_ptr<Pass>(new RelocationPass<Mips32ELType>(ctx));
case llvm::Triple::mips64el:
return std::unique_ptr<Pass>(new RelocationPass<Mips64ELType>(ctx));
default:
llvm_unreachable("Unhandled arch");
}
}
std::unique_ptr<Pass>
lld::elf::createMipsRelocationPass(MipsLinkingContext &ctx) {
switch (ctx.getOutputELFType()) {
case llvm::ELF::ET_EXEC:
case llvm::ELF::ET_DYN:
return std::unique_ptr<Pass>(new RelocationPass<Mips32ElELFType>(ctx));
return createPass(ctx);
case llvm::ELF::ET_REL:
return std::unique_ptr<Pass>();
default:

View File

@ -7,43 +7,19 @@
//
//===----------------------------------------------------------------------===//
#include "ELFFile.h"
#include "MipsDynamicLibraryWriter.h"
#include "MipsExecutableWriter.h"
#include "MipsLinkingContext.h"
#include "MipsTargetHandler.h"
using namespace lld;
using namespace elf;
MipsTargetHandler::MipsTargetHandler(MipsLinkingContext &ctx)
: _ctx(ctx), _runtimeFile(new MipsRuntimeFile<Mips32ElELFType>(ctx)),
_targetLayout(new MipsTargetLayout<Mips32ElELFType>(ctx)),
_relocationHandler(new MipsTargetRelocationHandler(*_targetLayout)) {}
std::unique_ptr<Writer> MipsTargetHandler::getWriter() {
switch (_ctx.getOutputELFType()) {
case llvm::ELF::ET_EXEC:
return std::unique_ptr<Writer>(
new MipsExecutableWriter<Mips32ElELFType>(_ctx, *_targetLayout));
case llvm::ELF::ET_DYN:
return std::unique_ptr<Writer>(
new MipsDynamicLibraryWriter<Mips32ElELFType>(_ctx, *_targetLayout));
case llvm::ELF::ET_REL:
llvm_unreachable("TODO: support -r mode");
default:
llvm_unreachable("unsupported output type");
}
}
void MipsTargetHandler::registerRelocationNames(Registry &registry) {
void MipsRelocationStringTable::registerTable(Registry &registry) {
registry.addKindTable(Reference::KindNamespace::ELF,
Reference::KindArch::Mips, kindStrings);
}
#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
const Registry::KindStrings MipsTargetHandler::kindStrings[] = {
const Registry::KindStrings MipsRelocationStringTable::kindStrings[] = {
#include "llvm/Support/ELFRelocs/Mips.def"
LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
LLD_KIND_STRING_ENTRY(LLD_R_MIPS_32_HI16),

View File

@ -10,7 +10,9 @@
#define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
#include "DefaultTargetHandler.h"
#include "MipsDynamicLibraryWriter.h"
#include "MipsELFReader.h"
#include "MipsExecutableWriter.h"
#include "MipsLinkingContext.h"
#include "MipsRelocationHandler.h"
#include "MipsSectionChunks.h"
@ -81,39 +83,63 @@ public:
: CRuntimeFile<ELFType>(ctx, "Mips runtime file") {}
};
/// \brief TargetHandler for Mips
class MipsTargetHandler final : public DefaultTargetHandler<Mips32ElELFType> {
public:
MipsTargetHandler(MipsLinkingContext &ctx);
/// \brief Auxiliary class holds relocation's names table.
class MipsRelocationStringTable {
static const Registry::KindStrings kindStrings[];
MipsTargetLayout<Mips32ElELFType> &getTargetLayout() override {
return *_targetLayout;
}
public:
static void registerTable(Registry &registry);
};
/// \brief TargetHandler for Mips
template <class ELFT>
class MipsTargetHandler final : public DefaultTargetHandler<ELFT> {
public:
MipsTargetHandler(MipsLinkingContext &ctx)
: _ctx(ctx), _runtimeFile(new MipsRuntimeFile<ELFT>(ctx)),
_targetLayout(new MipsTargetLayout<ELFT>(ctx)),
_relocationHandler(createMipsRelocationHandler<ELFT>(ctx)) {}
MipsTargetLayout<ELFT> &getTargetLayout() override { return *_targetLayout; }
std::unique_ptr<Reader> getObjReader(bool atomizeStrings) override {
return std::unique_ptr<Reader>(
new MipsELFObjectReader<Mips32ElELFType>(_ctx, atomizeStrings));
new MipsELFObjectReader<ELFT>(_ctx, atomizeStrings));
}
std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) override {
return std::unique_ptr<Reader>(
new MipsELFDSOReader<Mips32ElELFType>(_ctx, useShlibUndefines));
new MipsELFDSOReader<ELFT>(_ctx, useShlibUndefines));
}
const MipsTargetRelocationHandler &getRelocationHandler() const override {
const TargetRelocationHandler &getRelocationHandler() const override {
return *_relocationHandler;
}
std::unique_ptr<Writer> getWriter() override;
std::unique_ptr<Writer> getWriter() override {
switch (_ctx.getOutputELFType()) {
case llvm::ELF::ET_EXEC:
return std::unique_ptr<Writer>(
new MipsExecutableWriter<ELFT>(_ctx, *_targetLayout));
case llvm::ELF::ET_DYN:
return std::unique_ptr<Writer>(
new MipsDynamicLibraryWriter<ELFT>(_ctx, *_targetLayout));
case llvm::ELF::ET_REL:
llvm_unreachable("TODO: support -r mode");
default:
llvm_unreachable("unsupported output type");
}
}
void registerRelocationNames(Registry &registry) override;
void registerRelocationNames(Registry &registry) override {
MipsRelocationStringTable::registerTable(registry);
}
private:
static const Registry::KindStrings kindStrings[];
MipsLinkingContext &_ctx;
std::unique_ptr<MipsRuntimeFile<Mips32ElELFType>> _runtimeFile;
std::unique_ptr<MipsTargetLayout<Mips32ElELFType>> _targetLayout;
std::unique_ptr<MipsTargetRelocationHandler> _relocationHandler;
std::unique_ptr<MipsRuntimeFile<ELFT>> _runtimeFile;
std::unique_ptr<MipsTargetLayout<ELFT>> _targetLayout;
std::unique_ptr<TargetRelocationHandler> _relocationHandler;
};
template <class ELFT> class MipsSymbolTable : public SymbolTable<ELFT> {

View File

@ -0,0 +1,78 @@
# Check executable base address configuration. Base address should be
# equal to 0x400000 and the MIPS_BASE_ADDRESS dynamic tag's value should
# be the same.
# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips64el --noinhibit-exec -o %t.exe %t.o
# RUN: llvm-readobj -dynamic-table -program-headers %t.exe | FileCheck %s
# CHECK: DynamicSection [ (13 entries)
# CHECK: Tag Type Name/Value
# CHECK-NEXT: 0x0000000000000004 HASH 0x{{[0-9A-F]+}}
# CHECK-NEXT: 0x0000000000000005 STRTAB 0x{{[0-9A-F]+}}
# CHECK-NEXT: 0x0000000000000006 SYMTAB 0x{{[0-9A-F]+}}
# CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes)
# CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes)
# CHECK-NEXT: 0x0000000070000001 MIPS_RLD_VERSION 1
# CHECK-NEXT: 0x0000000070000005 MIPS_FLAGS NOTPOT
# CHECK-NEXT: 0x0000000070000006 MIPS_BASE_ADDRESS 0x120000000
# CHECK-NEXT: 0x000000007000000A MIPS_LOCAL_GOTNO 2
# CHECK-NEXT: 0x0000000070000011 MIPS_SYMTABNO 1
# CHECK-NEXT: 0x0000000070000013 MIPS_GOTSYM 0x1
# CHECK-NEXT: 0x0000000000000003 PLTGOT 0x120001000
# CHECK-NEXT: 0x0000000000000000 NULL 0x0
# CHECK-NEXT: ]
# CHECK: ProgramHeaders [
# CHECK: ProgramHeader {
# CHECK: Type: PT_PHDR (0x6)
# CHECK: Offset: 0x40
# CHECK: VirtualAddress: 0x{{[0-9A-F]+}}
# CHECK: }
# CHECK: ProgramHeader {
# CHECK: Type: PT_INTERP (0x3)
# CHECK: Offset: 0x190
# CHECK: VirtualAddress: 0x{{[0-9A-F]+}}
# CHECK: }
# CHECK: ProgramHeader {
# CHECK: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x120000000
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
EF_MIPS_ARCH_64R2 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x10
Size: 0x00
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x10
Size: 0x00
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
- Name: .data
Type: STT_SECTION
Section: .data
- Name: .bss
Type: STT_SECTION
Section: .bss
Global:
- Name: main
Section: .text

View File

@ -0,0 +1,72 @@
# Check ELF Header for 64-bit shared library.
# Build shared library
# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips64el -shared -o %t.so %t.o
# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
# CHECK: Format: ELF64-mips
# CHECK: Arch: mips64el
# CHECK: AddressSize: 64bit
# CHECK: LoadName:
# CHECK: ElfHeader {
# CHECK: Ident {
# CHECK: Magic: (7F 45 4C 46)
# CHECK: Class: 64-bit (0x2)
# CHECK: DataEncoding: LittleEndian (0x1)
# CHECK: FileVersion: 1
# CHECK: OS/ABI: SystemV (0x0)
# CHECK: ABIVersion: 0
# CHECK: Unused: (00 00 00 00 00 00 00)
# CHECK: }
# CHECK: Type: SharedObject (0x3)
# CHECK: Machine: EM_MIPS (0x8)
# CHECK: Version: 1
# CHECK: Entry: 0x170
# CHECK: ProgramHeaderOffset: 0x40
# CHECK: SectionHeaderOffset: 0x2140
# CHECK: Flags [ (0x80000006)
# CHECK: EF_MIPS_ARCH_64R2 (0x80000000)
# CHECK: EF_MIPS_CPIC (0x4)
# CHECK: EF_MIPS_PIC (0x2)
# CHECK: ]
# CHECK: HeaderSize: 64
# CHECK: ProgramHeaderEntrySize: 56
# CHECK: ProgramHeaderCount: 4
# CHECK: SectionHeaderEntrySize: 64
# CHECK: SectionHeaderCount: 11
# CHECK: StringTableSectionIndex: 8
# CHECK: }
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64R2 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
- Name: .data
Type: STT_SECTION
Section: .data
Global:
- Name: data
Type: STT_OBJECT
Section: .data
Size: 0x04
...

View File

@ -0,0 +1,75 @@
# Check ELF Header for shared library in case of microMIPS symbols.
# Build shared library
# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips64el -shared -o %t.so %t.o
# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
# CHECK: Format: ELF64-mips
# CHECK-NEXT: Arch: mips64el
# CHECK-NEXT: AddressSize: 64bit
# CHECK-NEXT: LoadName:
# CHECK-NEXT: ElfHeader {
# CHECK-NEXT: Ident {
# CHECK-NEXT: Magic: (7F 45 4C 46)
# CHECK-NEXT: Class: 64-bit (0x2)
# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
# CHECK-NEXT: FileVersion: 1
# CHECK-NEXT: OS/ABI: SystemV (0x0)
# CHECK-NEXT: ABIVersion: 0
# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
# CHECK-NEXT: }
# CHECK-NEXT: Type: SharedObject (0x3)
# CHECK-NEXT: Machine: EM_MIPS (0x8)
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: 0x170
# CHECK-NEXT: ProgramHeaderOffset: 0x40
# CHECK-NEXT: SectionHeaderOffset: 0x2140
# CHECK-NEXT: Flags [ (0x82000007)
# CHECK-NEXT: EF_MIPS_ARCH_64R2 (0x80000000)
# CHECK-NEXT: EF_MIPS_CPIC (0x4)
# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000)
# CHECK-NEXT: EF_MIPS_NOREORDER (0x1)
# CHECK-NEXT: EF_MIPS_PIC (0x2)
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 64
# CHECK-NEXT: ProgramHeaderEntrySize: 56
# CHECK-NEXT: ProgramHeaderCount: 4
# CHECK-NEXT: SectionHeaderEntrySize: 64
# CHECK-NEXT: SectionHeaderCount: 11
# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT:}
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
EF_MIPS_MICROMIPS, EF_MIPS_ARCH_64R2 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
- Name: .data
Type: STT_SECTION
Section: .data
Global:
- Name: foo
Type: STT_FUNC
Section: .text
Size: 0x08
Other: [ STO_MIPS_MICROMIPS ]

View File

@ -0,0 +1,30 @@
# Check that the linker shows an error when object
# file has unsupported ASE flags.
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-mips16.o
# RUN: not lld -flavor gnu -target mips64el -e T -o %t.exe %t-mips16.o 2>&1 | \
# RUN: FileCheck -check-prefix=MIPS16 %s
# MIPS16: Unsupported extension: MIPS16
# mips16.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64, EF_MIPS_ARCH_ASE_M16]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Global:
- Name: T
Section: .text
...

View File

@ -0,0 +1,33 @@
# 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 mips64el -e T -o %t.exe %t.o
# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
# CHECK: Flags [ (0x62000001)
# CHECK-NEXT: EF_MIPS_ARCH_64 (0x60000000)
# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000)
# CHECK-NEXT: EF_MIPS_NOREORDER (0x1)
# CHECK-NEXT: ]
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_ARCH_64, EF_MIPS_NOREORDER, EF_MIPS_MICROMIPS ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Global:
- Name: T
Section: .text
...

View File

@ -0,0 +1,130 @@
# 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 mips64el -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 mips64el -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 mips64el -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 mips64el -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 [ (0x60000004)
# ABI-CALLS1-NEXT: EF_MIPS_ARCH_64 (0x60000000)
# ABI-CALLS1-NEXT: EF_MIPS_CPIC (0x4)
# ABI-CALLS1-NEXT: ]
# ABI-CALLS2: Flags [ (0x60000004)
# ABI-CALLS2-NEXT: EF_MIPS_ARCH_64 (0x60000000)
# ABI-CALLS2-NEXT: EF_MIPS_CPIC (0x4)
# ABI-CALLS2-NEXT: ]
# CPIC: Flags [ (0x60000004)
# CPIC-NEXT: EF_MIPS_ARCH_64 (0x60000000)
# CPIC-NEXT: EF_MIPS_CPIC (0x4)
# CPIC-NEXT: ]
# BOTH: Flags [ (0x60000006)
# BOTH-NEXT: EF_MIPS_ARCH_64 (0x60000000)
# BOTH-NEXT: EF_MIPS_CPIC (0x4)
# BOTH-NEXT: EF_MIPS_PIC (0x2)
# BOTH-NEXT: ]
# none.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: 0x10
Size: 0x08
Symbols:
Global:
- Name: T1
Section: .text
# cpic.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64, EF_MIPS_CPIC]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Global:
- Name: T2
Section: .text
# pic.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64, EF_MIPS_PIC]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Global:
- Name: T3
Section: .text
# both.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64, EF_MIPS_CPIC, EF_MIPS_PIC]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Global:
- Name: T4
Section: .text
...

View File

@ -0,0 +1,64 @@
# 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 mips64el -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 [ (0x82000001)
# CHECK-NEXT: EF_MIPS_ARCH_64R2 (0x80000000)
# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000)
# CHECK-NEXT: EF_MIPS_NOREORDER (0x1)
# CHECK-NEXT: ]
# none.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_5]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
# noreorder.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64, EF_MIPS_NOREORDER]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
# micro.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64R2, EF_MIPS_MICROMIPS]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
...

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 mips64el -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: 0x10
Size: 0x08
...

View File

@ -0,0 +1,79 @@
# Check selecting ELF header ARCH flag.
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-m3.o
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-m5.o
# RUN: yaml2obj -format=elf -docnum 3 %s > %t-m64.o
# RUN: yaml2obj -format=elf -docnum 4 %s > %t-m64r2.o
# RUN: lld -flavor gnu -target mips64el -shared -o %t.so \
# RUN: %t-m64.o %t-m5.o %t-m64r2.o %t-m3.o
# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
# CHECK: Flags [ (0x80000000)
# CHECK-NEXT: EF_MIPS_ARCH_64R2 (0x80000000)
# CHECK-NEXT: ]
# m3.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_3]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
# m5.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_5]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
# m64.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: 0x10
Size: 0x08
# m64r2.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64R2]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
...

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 mips64el -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: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ARCH_64, EF_MIPS_NAN2008]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
# legacy.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: 0x10
Size: 0x08
...

View File

@ -0,0 +1,66 @@
# Check ELF Header for 64-bit executable file.
# Build executable
# RUN: yaml2obj -format=elf %s > %t-o.o
# RUN: lld -flavor gnu -target mips64el -e glob -o %t.exe %t-o.o
# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
# CHECK: Format: ELF64-mips
# CHECK: Arch: mips64el
# CHECK: AddressSize: 64bit
# CHECK: LoadName:
# CHECK: ElfHeader {
# CHECK: Ident {
# CHECK: Magic: (7F 45 4C 46)
# CHECK: Class: 64-bit (0x2)
# CHECK: DataEncoding: LittleEndian (0x1)
# CHECK: FileVersion: 1
# CHECK: OS/ABI: SystemV (0x0)
# CHECK: ABIVersion: 0
# CHECK: Unused: (00 00 00 00 00 00 00)
# CHECK: }
# CHECK: Type: Executable (0x2)
# CHECK: Machine: EM_MIPS (0x8)
# CHECK: Version: 1
# CHECK: Entry: 0x1200001A0
# CHECK: ProgramHeaderOffset: 0x40
# CHECK: SectionHeaderOffset: 0x12F8
# CHECK: Flags [ (0x60000007)
# CHECK: EF_MIPS_ARCH_64 (0x60000000)
# CHECK: EF_MIPS_CPIC (0x4)
# CHECK: EF_MIPS_NOREORDER (0x1)
# CHECK: EF_MIPS_PIC (0x2)
# CHECK: ]
# CHECK: HeaderSize: 64
# CHECK: ProgramHeaderEntrySize: 56
# CHECK: ProgramHeaderCount: 5
# CHECK: SectionHeaderEntrySize: 64
# CHECK: SectionHeaderCount: 11
# CHECK: StringTableSectionIndex: 8
# CHECK: }
# o.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
EF_MIPS_ARCH_64 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
Global:
- Name: glob
Section: .text
...

View File

@ -0,0 +1,68 @@
# Check ELF Header for 64-bit executable file in case of microMIPS entry symbol.
# Build executable
# RUN: yaml2obj -format=elf %s > %t-o.o
# RUN: lld -flavor gnu -target mips64el -e glob -o %t.exe %t-o.o
# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
# CHECK: Format: ELF64-mips
# CHECK: Arch: mips64el
# CHECK: AddressSize: 64bit
# CHECK: LoadName:
# CHECK: ElfHeader {
# CHECK: Ident {
# CHECK: Magic: (7F 45 4C 46)
# CHECK: Class: 64-bit (0x2)
# CHECK: DataEncoding: LittleEndian (0x1)
# CHECK: FileVersion: 1
# CHECK: OS/ABI: SystemV (0x0)
# CHECK: ABIVersion: 0
# CHECK: Unused: (00 00 00 00 00 00 00)
# CHECK: }
# CHECK: Type: Executable (0x2)
# CHECK: Machine: EM_MIPS (0x8)
# CHECK: Version: 1
# CHECK: Entry: 0x1200001A1
# CHECK: ProgramHeaderOffset: 0x40
# CHECK: SectionHeaderOffset: 0x12F8
# CHECK: Flags [ (0x82000007)
# CHECK: EF_MIPS_ARCH_64R2 (0x80000000)
# CHECK: EF_MIPS_CPIC (0x4)
# CHECK: EF_MIPS_MICROMIPS (0x2000000)
# CHECK: EF_MIPS_NOREORDER (0x1)
# CHECK: EF_MIPS_PIC (0x2)
# CHECK: ]
# CHECK: HeaderSize: 64
# CHECK: ProgramHeaderEntrySize: 56
# CHECK: ProgramHeaderCount: 5
# CHECK: SectionHeaderEntrySize: 64
# CHECK: SectionHeaderCount: 11
# CHECK: StringTableSectionIndex: 8
# CHECK: }
# o.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
EF_MIPS_MICROMIPS, EF_MIPS_ARCH_64R2 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
Global:
- Name: glob
Section: .text
Other: [ STO_MIPS_MICROMIPS ]
...

View File

@ -0,0 +1,26 @@
# Check program interpreter setup.
# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips64el -e main -o %t.exe %t.o
# RUN: llvm-objdump -s %t.exe | FileCheck %s
# CHECK: Contents of section .interp:
# CHECK-NEXT: {{[0-9a-f]+}} 2f6c6962 36342f6c 642e736f 2e3100 /lib64/ld.so.1.
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Size: 0x08
Symbols:
Global:
- Name: main
Section: .text