summaryrefslogtreecommitdiffstats
path: root/lld
diff options
context:
space:
mode:
Diffstat (limited to 'lld')
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp3
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp1
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp15
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h3
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp28
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h5
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp43
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h20
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp13
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp28
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h54
-rw-r--r--lld/test/elf/Mips/base-address-64.test78
-rw-r--r--lld/test/elf/Mips/dynlib-fileheader-64.test72
-rw-r--r--lld/test/elf/Mips/dynlib-fileheader-micro-64.test75
-rw-r--r--lld/test/elf/Mips/e-flags-merge-1-64.test30
-rw-r--r--lld/test/elf/Mips/e-flags-merge-2-64.test33
-rw-r--r--lld/test/elf/Mips/e-flags-merge-3-64.test130
-rw-r--r--lld/test/elf/Mips/e-flags-merge-4-64.test64
-rw-r--r--lld/test/elf/Mips/e-flags-merge-5-64.test42
-rw-r--r--lld/test/elf/Mips/e-flags-merge-6-64.test79
-rw-r--r--lld/test/elf/Mips/e-flags-merge-7-64.test42
-rw-r--r--lld/test/elf/Mips/exe-fileheader-64.test66
-rw-r--r--lld/test/elf/Mips/exe-fileheader-micro-64.test68
-rw-r--r--lld/test/elf/Mips/interpreter-64.test26
24 files changed, 942 insertions, 76 deletions
diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp
index 67d0e6812af..8d655a54443 100644
--- a/lld/lib/Driver/GnuLdDriver.cpp
+++ b/lld/lib/Driver/GnuLdDriver.cpp
@@ -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")
diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
index 058173ce027..446ac902121 100644
--- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
@@ -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;
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
index 1e7b41dde93..595f9c2777d 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
@@ -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 ...
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h
index 1067f97f280..6ade86f0163 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h
@@ -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;
};
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
index 2982423101c..2b05c163407 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
@@ -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) {
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
index 38231a5ec2c..cdedd3a9a36 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
@@ -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:
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
index 5d118f81673..5765ce1f062 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
@@ -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));
+}
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
index fb4f755e9d8..b70dfa29fff 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
@@ -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 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;
+class MipsLinkingContext;
+class TargetRelocationHandler;
-private:
- MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
-};
+template <class ELFT>
+std::unique_ptr<TargetRelocationHandler>
+createMipsRelocationHandler(MipsLinkingContext &ctx);
} // elf
} // lld
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
index e4e6c101afc..6f30f5f583e 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
@@ -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:
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
index ed80a48e444..408c56b5963 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
@@ -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),
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
index b8f91eac9a6..056f418f8f2 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
@@ -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 Auxiliary class holds relocation's names table.
+class MipsRelocationStringTable {
+ static const Registry::KindStrings kindStrings[];
+
+public:
+ static void registerTable(Registry &registry);
+};
+
/// \brief TargetHandler for Mips
-class MipsTargetHandler final : public DefaultTargetHandler<Mips32ElELFType> {
+template <class ELFT>
+class MipsTargetHandler final : public DefaultTargetHandler<ELFT> {
public:
- MipsTargetHandler(MipsLinkingContext &ctx);
+ MipsTargetHandler(MipsLinkingContext &ctx)
+ : _ctx(ctx), _runtimeFile(new MipsRuntimeFile<ELFT>(ctx)),
+ _targetLayout(new MipsTargetLayout<ELFT>(ctx)),
+ _relocationHandler(createMipsRelocationHandler<ELFT>(ctx)) {}
- MipsTargetLayout<Mips32ElELFType> &getTargetLayout() override {
- return *_targetLayout;
- }
+ 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> {
diff --git a/lld/test/elf/Mips/base-address-64.test b/lld/test/elf/Mips/base-address-64.test
new file mode 100644
index 00000000000..07110e7f918
--- /dev/null
+++ b/lld/test/elf/Mips/base-address-64.test
@@ -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
diff --git a/lld/test/elf/Mips/dynlib-fileheader-64.test b/lld/test/elf/Mips/dynlib-fileheader-64.test
new file mode 100644
index 00000000000..206f4fa7794
--- /dev/null
+++ b/lld/test/elf/Mips/dynlib-fileheader-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/dynlib-fileheader-micro-64.test b/lld/test/elf/Mips/dynlib-fileheader-micro-64.test
new file mode 100644
index 00000000000..c03a951671e
--- /dev/null
+++ b/lld/test/elf/Mips/dynlib-fileheader-micro-64.test
@@ -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 ]
diff --git a/lld/test/elf/Mips/e-flags-merge-1-64.test b/lld/test/elf/Mips/e-flags-merge-1-64.test
new file mode 100644
index 00000000000..d5719539baa
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-1-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/e-flags-merge-2-64.test b/lld/test/elf/Mips/e-flags-merge-2-64.test
new file mode 100644
index 00000000000..a169e7ea164
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-2-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/e-flags-merge-3-64.test b/lld/test/elf/Mips/e-flags-merge-3-64.test
new file mode 100644
index 00000000000..54065a63fb9
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-3-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/e-flags-merge-4-64.test b/lld/test/elf/Mips/e-flags-merge-4-64.test
new file mode 100644
index 00000000000..9ffa6134371
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-4-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/e-flags-merge-5-64.test b/lld/test/elf/Mips/e-flags-merge-5-64.test
new file mode 100644
index 00000000000..e629aedbc15
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-5-64.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 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
+...
diff --git a/lld/test/elf/Mips/e-flags-merge-6-64.test b/lld/test/elf/Mips/e-flags-merge-6-64.test
new file mode 100644
index 00000000000..fbc32b7135b
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-6-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/e-flags-merge-7-64.test b/lld/test/elf/Mips/e-flags-merge-7-64.test
new file mode 100644
index 00000000000..07ed6bb5483
--- /dev/null
+++ b/lld/test/elf/Mips/e-flags-merge-7-64.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 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
+...
diff --git a/lld/test/elf/Mips/exe-fileheader-64.test b/lld/test/elf/Mips/exe-fileheader-64.test
new file mode 100644
index 00000000000..b4b593471ac
--- /dev/null
+++ b/lld/test/elf/Mips/exe-fileheader-64.test
@@ -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
+...
diff --git a/lld/test/elf/Mips/exe-fileheader-micro-64.test b/lld/test/elf/Mips/exe-fileheader-micro-64.test
new file mode 100644
index 00000000000..90aa127a9e4
--- /dev/null
+++ b/lld/test/elf/Mips/exe-fileheader-micro-64.test
@@ -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 ]
+...
diff --git a/lld/test/elf/Mips/interpreter-64.test b/lld/test/elf/Mips/interpreter-64.test
new file mode 100644
index 00000000000..3ece3e6a467
--- /dev/null
+++ b/lld/test/elf/Mips/interpreter-64.test
@@ -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
OpenPOWER on IntegriCloud