[lld] r224826 - [Mips] Support linking of microMIPS 32-bit code

Simon Atanasyan simon at atanasyan.com
Wed Dec 24 13:04:06 PST 2014


Author: atanasyan
Date: Wed Dec 24 15:04:05 2014
New Revision: 224826

URL: http://llvm.org/viewvc/llvm-project?rev=224826&view=rev
Log:
[Mips] Support linking of microMIPS 32-bit code

The change is rather large but mainly it just adds handling of new relocations,
PLT entries etc.

Added:
    lld/trunk/test/elf/Mips/dynlib-dynsym-micro.test
    lld/trunk/test/elf/Mips/exe-dynsym-micro.test
    lld/trunk/test/elf/Mips/exe-got-micro.test
    lld/trunk/test/elf/Mips/got16-micro.test
    lld/trunk/test/elf/Mips/gp-sym-1-micro.test
    lld/trunk/test/elf/Mips/hilo16-8-micro.test
    lld/trunk/test/elf/Mips/hilo16-9-micro.test
    lld/trunk/test/elf/Mips/jalx-align-err.test
    lld/trunk/test/elf/Mips/jalx-bit-err.test
    lld/trunk/test/elf/Mips/jump-fix-err.test
    lld/trunk/test/elf/Mips/la25-stub-micro.test
    lld/trunk/test/elf/Mips/pc23-range.test
    lld/trunk/test/elf/Mips/plt-entry-mixed-1.test
    lld/trunk/test/elf/Mips/plt-entry-mixed-2.test
    lld/trunk/test/elf/Mips/plt-entry-mixed-3.test
    lld/trunk/test/elf/Mips/plt-entry-mixed-4.test
    lld/trunk/test/elf/Mips/plt-header-micro.test
    lld/trunk/test/elf/Mips/plt-header-mixed.test
    lld/trunk/test/elf/Mips/r26-1-micro.test
    lld/trunk/test/elf/Mips/r26-2-micro.test
    lld/trunk/test/elf/Mips/rel-copy-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-01-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-03-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-04-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-05-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-08-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-09-micro.test
    lld/trunk/test/elf/Mips/rel-dynamic-10-micro.test
    lld/trunk/test/elf/Mips/rel-pc7-10-16-23.test
    lld/trunk/test/elf/Mips/tls-1-micro.test
    lld/trunk/test/elf/Mips/tls-2-micro.test
    lld/trunk/test/elf/Mips/tls-3-micro.test
    lld/trunk/test/elf/Mips/tls-4-micro.test
    lld/trunk/test/elf/Mips/tls-5-micro.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Wed Dec 24 15:04:05 2014
@@ -182,6 +182,15 @@ private:
     }
   }
 
+  static Reference::Addend readAddend(const uint8_t *data, uint32_t mask,
+                                      bool shuffle) {
+    using namespace llvm::support;
+    uint32_t ins = endian::read<uint32_t, ELFT::TargetEndianness, 1>(data);
+    if (shuffle)
+      ins = ((ins & 0xffff) << 16) | ((ins & 0xffff0000) >> 16);
+    return ins & mask;
+  }
+
   Reference::Addend getAddend(const Elf_Rel &ri,
                               const ArrayRef<uint8_t> content) const {
     using namespace llvm::support;
@@ -190,9 +199,9 @@ private:
     case llvm::ELF::R_MIPS_32:
     case llvm::ELF::R_MIPS_GPREL32:
     case llvm::ELF::R_MIPS_PC32:
-      return endian::read<int32_t, ELFT::TargetEndianness, 2>(ap);
+      return readAddend(ap, 0xffffffff, false);
     case llvm::ELF::R_MIPS_26:
-      return endian::read<int32_t, ELFT::TargetEndianness, 2>(ap) & 0x3ffffff;
+      return readAddend(ap, 0x3ffffff, false) << 2;
     case llvm::ELF::R_MIPS_HI16:
     case llvm::ELF::R_MIPS_LO16:
     case llvm::ELF::R_MIPS_GOT16:
@@ -200,11 +209,34 @@ private:
     case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
     case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
     case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
-      return endian::read<int16_t, ELFT::TargetEndianness, 2>(ap);
+      return readAddend(ap, 0xffff, false);
+    case llvm::ELF::R_MICROMIPS_TLS_DTPREL_HI16:
+    case llvm::ELF::R_MICROMIPS_TLS_DTPREL_LO16:
+    case llvm::ELF::R_MICROMIPS_TLS_TPREL_HI16:
+    case llvm::ELF::R_MICROMIPS_TLS_TPREL_LO16:
+      return readAddend(ap, 0xffff, true);
+    case llvm::ELF::R_MICROMIPS_26_S1:
+      return readAddend(ap, 0x3ffffff, true) << 1;
+    case llvm::ELF::R_MICROMIPS_HI16:
+    case llvm::ELF::R_MICROMIPS_LO16:
+    case llvm::ELF::R_MICROMIPS_GOT16:
+      return readAddend(ap, 0xffff, true);
+    case llvm::ELF::R_MICROMIPS_PC16_S1:
+      return readAddend(ap, 0xffff, true) << 1;
+    case llvm::ELF::R_MICROMIPS_PC7_S1:
+      return readAddend(ap, 0x7f, false) << 1;
+    case llvm::ELF::R_MICROMIPS_PC10_S1:
+      return readAddend(ap, 0x3ff, false) << 1;
+    case llvm::ELF::R_MICROMIPS_PC23_S2:
+      return readAddend(ap, 0x7fffff, true) << 2;
     case llvm::ELF::R_MIPS_CALL16:
     case llvm::ELF::R_MIPS_TLS_GD:
     case llvm::ELF::R_MIPS_TLS_LDM:
     case llvm::ELF::R_MIPS_TLS_GOTTPREL:
+    case llvm::ELF::R_MICROMIPS_CALL16:
+    case llvm::ELF::R_MICROMIPS_TLS_GD:
+    case llvm::ELF::R_MICROMIPS_TLS_LDM:
+    case llvm::ELF::R_MICROMIPS_TLS_GOTTPREL:
       return 0;
     default:
       return 0;
@@ -218,6 +250,16 @@ private:
     case llvm::ELF::R_MIPS_GOT16:
       if (isLocalBinding(rel))
         return llvm::ELF::R_MIPS_LO16;
+      break;
+    case llvm::ELF::R_MICROMIPS_HI16:
+      return llvm::ELF::R_MICROMIPS_LO16;
+    case llvm::ELF::R_MICROMIPS_GOT16:
+      if (isLocalBinding(rel))
+        return llvm::ELF::R_MICROMIPS_LO16;
+      break;
+    default:
+      // Nothing to do.
+      break;
     }
     return llvm::ELF::R_MIPS_NONE;
   }

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Wed Dec 24 15:04:05 2014
@@ -20,6 +20,12 @@ MipsLinkingContext::MipsLinkingContext(l
     : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
                                     new MipsTargetHandler(*this))) {}
 
+uint32_t MipsLinkingContext::getMergedELFFlags() const {
+  const auto &handler = static_cast<MipsTargetHandler &>(
+      ELFLinkingContext::getTargetHandler<Mips32ElELFType>());
+  return handler.getELFFlagsMerger().getMergedELFFlags();
+}
+
 uint64_t MipsLinkingContext::getBaseAddress() const {
   if (_baseAddress == 0 && getOutputELFType() == llvm::ELF::ET_EXEC)
     return 0x400000;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Wed Dec 24 15:04:05 2014
@@ -27,7 +27,9 @@ enum {
   /// \brief Setup low 16 bits using the symbol this reference refers to.
   LLD_R_MIPS_LO16 = 1028,
   /// \brief Represents a reference between PLT and dynamic symbol.
-  LLD_R_MIPS_STO_PLT = 1029
+  LLD_R_MIPS_STO_PLT = 1029,
+  /// \brief The same as R_MICROMIPS_26_S1 but for global symbols.
+  LLD_R_MICROMIPS_GLOBAL_26_S1 = 1030,
 };
 
 typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType;
@@ -38,6 +40,8 @@ class MipsLinkingContext final : public
 public:
   MipsLinkingContext(llvm::Triple triple);
 
+  uint32_t getMergedELFFlags() const;
+
   // ELFLinkingContext
   uint64_t getBaseAddress() const override;
   StringRef entrySymbolName() const override;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Wed Dec 24 15:04:05 2014
@@ -39,21 +39,24 @@ void relocpc32(uint32_t &ins, uint64_t P
   applyReloc(ins, S + A - P, 0xffffffff);
 }
 
-/// \brief R_MIPS_26
+/// \brief R_MIPS_26, R_MICROMIPS_26_S1
 /// local   : ((A | ((P + 4) & 0x3F000000)) + S) >> 2
-static void reloc26loc(uint32_t &ins, uint64_t P, uint64_t S, int32_t A) {
-  uint32_t result = ((A << 2) | ((P + 4) & 0x3f000000)) + S;
-  applyReloc(ins, result >> 2, 0x03ffffff);
+static void reloc26loc(uint32_t &ins, uint64_t P, uint64_t S, int32_t A,
+                       uint32_t shift) {
+  uint32_t result = (A | ((P + 4) & (0xfc000000 << shift))) + S;
+  applyReloc(ins, result >> shift, 0x03ffffff);
 }
 
-/// \brief LLD_R_MIPS_GLOBAL_26
+/// \brief LLD_R_MIPS_GLOBAL_26, LLD_R_MICROMIPS_GLOBAL_26_S1
 /// external: (sign-extend(A) + S) >> 2
-static void reloc26ext(uint32_t &ins, uint64_t S, int32_t A) {
-  uint32_t result = signExtend<28>(A << 2) + S;
-  applyReloc(ins, result >> 2, 0x03ffffff);
+static void reloc26ext(uint32_t &ins, uint64_t S, int32_t A, uint32_t shift) {
+  uint32_t result = shift == 1 ? signExtend<27>(A) : signExtend<28>(A);
+  result += S;
+  applyReloc(ins, result >> shift, 0x03ffffff);
 }
 
 /// \brief R_MIPS_HI16, R_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_TPREL_HI16,
+/// R_MICROMIPS_HI16, R_MICROMIPS_TLS_DTPREL_HI16, R_MICROMIPS_TLS_TPREL_HI16,
 /// LLD_R_MIPS_HI16
 /// local/external: hi16 (AHL + S) - (short)(AHL + S) (truncate)
 /// _gp_disp      : hi16 (AHL + GP - P) - (short)(AHL + GP - P) (verify)
@@ -64,16 +67,17 @@ static void relocHi16(uint32_t &ins, uin
 }
 
 /// \brief R_MIPS_LO16, R_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_TPREL_LO16,
+/// R_MICROMIPS_LO16, R_MICROMIPS_TLS_DTPREL_LO16, R_MICROMIPS_TLS_TPREL_LO16,
 /// LLD_R_MIPS_LO16
 /// local/external: lo16 AHL + S (truncate)
 /// _gp_disp      : lo16 AHL + GP - P + 4 (verify)
 static void relocLo16(uint32_t &ins, uint64_t P, uint64_t S, int64_t AHL,
-                      bool isGPDisp) {
-  int32_t result = isGPDisp ? AHL + S - P + 4 : AHL + S;
+                      bool isGPDisp, bool micro) {
+  int32_t result = isGPDisp ? AHL + S - P + (micro ? 3 : 4) : AHL + S;
   applyReloc(ins, result, 0xffff);
 }
 
-/// \brief R_MIPS_GOT16, R_MIPS_CALL16
+/// \brief R_MIPS_GOT16, R_MIPS_CALL16, R_MICROMIPS_GOT16, R_MICROMIPS_CALL16
 /// rel16 G (verify)
 static void relocGOT(uint32_t &ins, uint64_t S, uint64_t GP) {
   int32_t G = (int32_t)(S - GP);
@@ -88,11 +92,102 @@ static void relocGPRel32(uint32_t &ins,
   applyReloc(ins, result, 0xffffffff);
 }
 
+/// \brief R_MICROMIPS_PC7_S1
+static void relocPc7(uint32_t &ins, uint64_t P, uint64_t S, int64_t A) {
+  A = signExtend<8>(A);
+  int32_t result = S + A - P;
+  applyReloc(ins, result >> 1, 0x7f);
+}
+
+/// \brief R_MICROMIPS_PC10_S1
+static void relocPc10(uint32_t &ins, uint64_t P, uint64_t S, int64_t A) {
+  A = signExtend<11>(A);
+  int32_t result = S + A - P;
+  applyReloc(ins, result >> 1, 0x3ff);
+}
+
+/// \brief R_MICROMIPS_PC16_S1
+static void relocPc16(uint32_t &ins, uint64_t P, uint64_t S, int64_t A) {
+  A = signExtend<17>(A);
+  int32_t result = S + A - P;
+  applyReloc(ins, result >> 1, 0xffff);
+}
+
+/// \brief R_MICROMIPS_PC23_S2
+static void relocPc23(uint32_t &ins, uint64_t P, uint64_t S, int64_t A) {
+  A = signExtend<25>(A);
+  int32_t result = S + A - P;
+
+  // Check addiupc 16MB range.
+  if (result + 0x1000000 >= 0x2000000)
+    llvm::errs() << "The addiupc instruction immediate "
+                 << llvm::format_hex(result, 10) << " is out of range.\n";
+  else
+    applyReloc(ins, result >> 2, 0x7fffff);
+}
+
 /// \brief LLD_R_MIPS_32_HI16
 static void reloc32hi16(uint32_t &ins, uint64_t S, int64_t A) {
   applyReloc(ins, (S + A + 0x8000) & 0xffff0000, 0xffffffff);
 }
 
+static void fixJumpOpCode(uint32_t &ins, uint64_t tgt, bool isMicro) {
+  uint32_t opNative = isMicro ? 0x3d : 0x03;
+  uint32_t opCross = isMicro ? 0x3c : 0x1d;
+
+  if (tgt & 2)
+    llvm::errs() << "The jalx target " << llvm::format_hex(tgt, 10)
+                 << " is not word-aligned.\n";
+
+  if ((tgt & 1) == isMicro)
+    llvm::errs() << "Incorrect bit 0 for the jalx target "
+                 << llvm::format_hex(tgt, 10) << ".\n";
+
+  uint8_t op = ins >> 26;
+  if (op != opNative && op != opCross)
+    llvm::errs() << "Unsupported jump opcode (" << llvm::format_hex(op, 4)
+                 << ") for ISA modes cross call.\n";
+  else
+    ins = (ins & ~(0x3f << 26)) | (opCross << 26);
+}
+
+static bool isMicroMipsAtom(const Atom *a) {
+  if (const auto *da = dyn_cast<DefinedAtom>(a))
+    return da->codeModel() == DefinedAtom::codeMipsMicro ||
+           da->codeModel() == DefinedAtom::codeMipsMicroPIC;
+  return false;
+}
+
+static bool needMicroShuffle(const Reference &ref) {
+  if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
+    return false;
+  assert(ref.kindArch() == Reference::KindArch::Mips);
+  switch (ref.kindValue()) {
+  case R_MICROMIPS_HI16:
+  case R_MICROMIPS_LO16:
+  case R_MICROMIPS_GOT16:
+  case R_MICROMIPS_PC16_S1:
+  case R_MICROMIPS_PC23_S2:
+  case R_MICROMIPS_CALL16:
+  case R_MICROMIPS_26_S1:
+  case R_MICROMIPS_TLS_GD:
+  case R_MICROMIPS_TLS_LDM:
+  case R_MICROMIPS_TLS_DTPREL_HI16:
+  case R_MICROMIPS_TLS_DTPREL_LO16:
+  case R_MICROMIPS_TLS_GOTTPREL:
+  case R_MICROMIPS_TLS_TPREL_HI16:
+  case R_MICROMIPS_TLS_TPREL_LO16:
+  case LLD_R_MICROMIPS_GLOBAL_26_S1:
+    return true;
+  default:
+    return false;
+  }
+}
+
+static uint32_t microShuffle(uint32_t ins) {
+  return ((ins & 0xffff) << 16) | ((ins & 0xffff0000) >> 16);
+}
+
 std::error_code MipsTargetRelocationHandler::applyRelocation(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
     const Reference &ref) const {
@@ -112,6 +207,31 @@ std::error_code MipsTargetRelocationHand
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
   uint32_t ins = endian::read<uint32_t, little, 2>(location);
 
+  bool shuffle = needMicroShuffle(ref);
+  if (shuffle)
+    ins = microShuffle(ins);
+
+  bool isSrcMicroMips = isMicroMipsAtom(atom._atom);
+  bool isTgtMicroMips = isMicroMipsAtom(ref.target());
+  bool isCrossJump = isSrcMicroMips != isTgtMicroMips;
+
+  if (isTgtMicroMips)
+    targetVAddress |= 1;
+
+  if (isCrossJump)
+    switch (ref.kindValue()) {
+    case R_MIPS_26:
+    case LLD_R_MIPS_GLOBAL_26:
+      fixJumpOpCode(ins, targetVAddress, false);
+      break;
+    case R_MICROMIPS_26_S1:
+    case LLD_R_MICROMIPS_GLOBAL_26_S1:
+      fixJumpOpCode(ins, targetVAddress, true);
+      break;
+    default:
+      break; // Do nothing.
+    }
+
   switch (ref.kindValue()) {
   case R_MIPS_NONE:
     break;
@@ -119,35 +239,73 @@ std::error_code MipsTargetRelocationHand
     reloc32(ins, targetVAddress, ref.addend());
     break;
   case R_MIPS_26:
-    reloc26loc(ins, relocVAddress, targetVAddress, ref.addend());
+    reloc26loc(ins, relocVAddress, targetVAddress, ref.addend(), 2);
+    break;
+  case R_MICROMIPS_26_S1:
+    reloc26loc(ins, relocVAddress, targetVAddress, ref.addend(),
+               isCrossJump ? 2 : 1);
     break;
   case R_MIPS_HI16:
     relocHi16(ins, relocVAddress, targetVAddress, ref.addend(), isGpDisp);
     break;
+  case R_MICROMIPS_HI16:
+    relocHi16(ins, relocVAddress, targetVAddress, ref.addend(), isGpDisp);
+    break;
   case R_MIPS_LO16:
-    relocLo16(ins, relocVAddress, targetVAddress, ref.addend(), isGpDisp);
+    relocLo16(ins, relocVAddress, targetVAddress, ref.addend(), isGpDisp,
+              false);
+    break;
+  case R_MICROMIPS_LO16:
+    relocLo16(ins, relocVAddress, targetVAddress, ref.addend(), isGpDisp,
+              true);
     break;
   case R_MIPS_GOT16:
   case R_MIPS_CALL16:
     relocGOT(ins, targetVAddress, gpAddr);
     break;
+  case R_MICROMIPS_GOT16:
+  case R_MICROMIPS_CALL16:
+    relocGOT(ins, targetVAddress, gpAddr);
+    break;
+  case R_MICROMIPS_PC7_S1:
+    relocPc7(ins, relocVAddress, targetVAddress, ref.addend());
+    break;
+  case R_MICROMIPS_PC10_S1:
+    relocPc10(ins, relocVAddress, targetVAddress, ref.addend());
+    break;
+  case R_MICROMIPS_PC16_S1:
+    relocPc16(ins, relocVAddress, targetVAddress, ref.addend());
+    break;
+  case R_MICROMIPS_PC23_S2:
+    relocPc23(ins, relocVAddress, targetVAddress, ref.addend());
+    break;
   case R_MIPS_TLS_GD:
   case R_MIPS_TLS_LDM:
   case R_MIPS_TLS_GOTTPREL:
+  case R_MICROMIPS_TLS_GD:
+  case R_MICROMIPS_TLS_LDM:
+  case R_MICROMIPS_TLS_GOTTPREL:
     relocGOT(ins, targetVAddress, gpAddr);
     break;
   case R_MIPS_TLS_DTPREL_HI16:
   case R_MIPS_TLS_TPREL_HI16:
+  case R_MICROMIPS_TLS_DTPREL_HI16:
+  case R_MICROMIPS_TLS_TPREL_HI16:
     relocHi16(ins, 0, targetVAddress, ref.addend(), false);
     break;
   case R_MIPS_TLS_DTPREL_LO16:
   case R_MIPS_TLS_TPREL_LO16:
-    relocLo16(ins, 0, targetVAddress, ref.addend(), false);
+    relocLo16(ins, 0, targetVAddress, ref.addend(), false, false);
+    break;
+  case R_MICROMIPS_TLS_DTPREL_LO16:
+  case R_MICROMIPS_TLS_TPREL_LO16:
+    relocLo16(ins, 0, targetVAddress, ref.addend(), false, true);
     break;
   case R_MIPS_GPREL32:
     relocGPRel32(ins, relocVAddress, targetVAddress, ref.addend(), gpAddr);
     break;
   case R_MIPS_JALR:
+  case R_MICROMIPS_JALR:
     // We do not do JALR optimization now.
     break;
   case R_MIPS_REL32:
@@ -168,13 +326,16 @@ std::error_code MipsTargetRelocationHand
     reloc32hi16(ins, targetVAddress, ref.addend());
     break;
   case LLD_R_MIPS_GLOBAL_26:
-    reloc26ext(ins, targetVAddress, ref.addend());
+    reloc26ext(ins, targetVAddress, ref.addend(), 2);
+    break;
+  case LLD_R_MICROMIPS_GLOBAL_26_S1:
+    reloc26ext(ins, targetVAddress, ref.addend(), isCrossJump ? 2 : 1);
     break;
   case LLD_R_MIPS_HI16:
     relocHi16(ins, 0, targetVAddress, 0, false);
     break;
   case LLD_R_MIPS_LO16:
-    relocLo16(ins, 0, targetVAddress, 0, false);
+    relocLo16(ins, 0, targetVAddress, 0, false, false);
     break;
   case LLD_R_MIPS_STO_PLT:
     // Do nothing.
@@ -183,6 +344,9 @@ std::error_code MipsTargetRelocationHand
     unhandledReferenceType(*atom._atom, ref);
   }
 
+  if (shuffle)
+    ins = microShuffle(ins);
+
   endian::write<uint32_t, little, 2>(location, ins);
   return std::error_code();
 }

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Wed Dec 24 15:04:05 2014
@@ -45,6 +45,19 @@ static const uint8_t mipsPlt0AtomContent
   0xfe, 0xff, 0x18, 0x27  // subu  $24, $24, 2
 };
 
+// microMIPS PLT0 entry
+static const uint8_t micromipsPlt0AtomContent[] = {
+  0x80, 0x79, 0x00, 0x00, // addiupc $3,  (&GOTPLT[0]) - .
+  0x23, 0xff, 0x00, 0x00, // lw      $25, 0($3)
+  0x35, 0x05,             // subu    $2,  $2, $3
+  0x25, 0x25,             // srl     $2,  $2, 2
+  0x02, 0x33, 0xfe, 0xff, // subu    $24, $2, 2
+  0xff, 0x0d,             // move    $15, $31
+  0xf9, 0x45,             // jalrs   $25
+  0x83, 0x0f,             // move    $28, $3
+  0x00, 0x0c              // nop
+};
+
 // Regular PLT entry
 static const uint8_t mipsPltAAtomContent[] = {
   0x00, 0x00, 0x0f, 0x3c, // lui   $15, %hi(.got.plt entry)
@@ -53,6 +66,14 @@ static const uint8_t mipsPltAAtomContent
   0x00, 0x00, 0xf8, 0x25  // addiu $24, $15, %lo(.got.plt entry)
 };
 
+// microMIPS PLT entry
+static const uint8_t micromipsPltAtomContent[] = {
+  0x00, 0x79, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
+  0x22, 0xff, 0x00, 0x00, // lw $25, 0($2)
+  0x99, 0x45,             // jr $25
+  0x02, 0x0f              // move $24, $2
+};
+
 // LA25 stub entry
 static const uint8_t mipsLA25AtomContent[] = {
   0x00, 0x00, 0x19, 0x3c, // lui   $25, %hi(func)
@@ -61,6 +82,14 @@ static const uint8_t mipsLA25AtomContent
   0x00, 0x00, 0x00, 0x00  // nop
 };
 
+// microMIPS LA25 stub entry
+static const uint8_t micromipsLA25AtomContent[] = {
+  0xb9, 0x41, 0x00, 0x00, // lui   $25, %hi(func)
+  0x00, 0xd4, 0x00, 0x00, // j     func
+  0x39, 0x33, 0x00, 0x00, // addiu $25, $25, %lo(func)
+  0x00, 0x00, 0x00, 0x00  // nop
+};
+
 namespace {
 
 /// \brief Abstract base class represent MIPS GOT entries.
@@ -101,6 +130,26 @@ public:
   }
 };
 
+class GOTPLTAtom : public GOTAtom {
+public:
+  GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
+  GOTPLTAtom(const Atom *a, const File &f) : GOTAtom(f, ".got.plt") {
+    // Create dynamic relocation to adjust the .got.plt entry at runtime.
+    addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
+  }
+
+  /// Setup reference to assign initial value to the .got.plt entry.
+  void setPLT0(const PLTAtom *plt0) {
+    addReferenceELF_Mips(R_MIPS_32, 0, plt0, 0);
+  }
+
+  Alignment alignment() const override { return Alignment(2); }
+
+  ArrayRef<uint8_t> rawContent() const override {
+    return llvm::makeArrayRef(mipsGot0AtomContent);
+  }
+};
+
 class PLT0Atom : public PLTAtom {
 public:
   PLT0Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
@@ -115,9 +164,23 @@ public:
   }
 };
 
+class PLT0MicroAtom : public PLTAtom {
+public:
+  PLT0MicroAtom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
+    // Setup reference to fixup the PLT0 entry.
+    addReferenceELF_Mips(R_MICROMIPS_PC23_S2, 0, got, 0);
+  }
+
+  CodeModel codeModel() const override { return codeMipsMicro; }
+
+  ArrayRef<uint8_t> rawContent() const override {
+    return llvm::makeArrayRef(micromipsPlt0AtomContent);
+  }
+};
+
 class PLTAAtom : public PLTAtom {
 public:
-  PLTAAtom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
+  PLTAAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
     // Setup reference to fixup the PLT entry.
     addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, got, 0);
     addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, got, 0);
@@ -129,29 +192,29 @@ public:
   }
 };
 
-/// \brief MIPS GOT PLT entry
-class GOTPLTAtom : public GOTAtom {
+class PLTMicroAtom : public PLTAtom {
 public:
-  GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
-  GOTPLTAtom(const PLTAtom *plt0, const Atom *a, const File &f)
-      : GOTAtom(f, ".got.plt") {
-    // Setup reference to assign initial value to the .got.plt entry.
-    addReferenceELF_Mips(R_MIPS_32, 0, plt0, 0);
-    // Create dynamic relocation to adjust the .got.plt entry at runtime.
-    addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
+  PLTMicroAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
+    // Setup reference to fixup the microMIPS PLT entry.
+    addReferenceELF_Mips(R_MICROMIPS_PC23_S2, 0, got, 0);
   }
 
-  Alignment alignment() const override { return Alignment(2); }
+  Alignment alignment() const override { return Alignment(1); }
+  CodeModel codeModel() const override { return codeMipsMicro; }
 
   ArrayRef<uint8_t> rawContent() const override {
-    return llvm::makeArrayRef(mipsGot0AtomContent);
+    return llvm::makeArrayRef(micromipsPltAtomContent);
   }
 };
 
-/// \brief LA25 stub atom
 class LA25Atom : public PLTAtom {
 public:
-  LA25Atom(const Atom *a, const File &f) : PLTAtom(f, ".text") {
+  LA25Atom(const File &f) : PLTAtom(f, ".text") {}
+};
+
+class LA25RegAtom : public LA25Atom {
+public:
+  LA25RegAtom(const Atom *a, const File &f) : LA25Atom(f) {
     // Setup reference to fixup the LA25 stub entry.
     addReferenceELF_Mips(R_MIPS_HI16, 0, a, 0);
     addReferenceELF_Mips(R_MIPS_26, 4, a, 0);
@@ -163,6 +226,22 @@ public:
   }
 };
 
+class LA25MicroAtom : public LA25Atom {
+public:
+  LA25MicroAtom(const Atom *a, const File &f) : LA25Atom(f) {
+    // Setup reference to fixup the microMIPS LA25 stub entry.
+    addReferenceELF_Mips(R_MICROMIPS_HI16, 0, a, 0);
+    addReferenceELF_Mips(R_MICROMIPS_26_S1, 4, a, 0);
+    addReferenceELF_Mips(R_MICROMIPS_LO16, 8, a, 0);
+  }
+
+  CodeModel codeModel() const override { return codeMipsMicro; }
+
+  ArrayRef<uint8_t> rawContent() const override {
+    return llvm::makeArrayRef(micromipsLA25AtomContent);
+  }
+};
+
 class RelocationPassFile : public SimpleFile {
 public:
   RelocationPassFile(const ELFLinkingContext &ctx)
@@ -199,7 +278,7 @@ private:
   /// \brief Map Atoms to TLS GD GOT entries.
   llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSGdMap;
 
-  /// \brief GOT entry for the R_MIPS_TLS_LDM relocation.
+  /// \brief GOT entry for the R_xxxMIPS_TLS_LDM relocations.
   GOTTLSGdAtom *_gotLDMEntry;
 
   /// \brief the list of local GOT atoms.
@@ -211,14 +290,19 @@ private:
   /// \brief the list of TLS GOT atoms.
   std::vector<GOTAtom *> _tlsGotVector;
 
+  /// \brief Map Atoms to their GOTPLT entries.
+  llvm::DenseMap<const Atom *, GOTPLTAtom *> _gotpltMap;
+
   /// \brief Map Atoms to their PLT entries.
-  llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
+  llvm::DenseMap<const Atom *, PLTAAtom *> _pltRegMap;
+  llvm::DenseMap<const Atom *, PLTMicroAtom *> _pltMicroMap;
 
   /// \brief Map Atoms to their Object entries.
   llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
 
   /// \brief Map Atoms to their LA25 entries.
-  llvm::DenseMap<const Atom *, LA25Atom *> _la25Map;
+  llvm::DenseMap<const Atom *, LA25RegAtom *> _la25RegMap;
+  llvm::DenseMap<const Atom *, LA25MicroAtom *> _la25MicroMap;
 
   /// \brief Atoms referenced by static relocations.
   llvm::DenseSet<const Atom *> _hasStaticRelocations;
@@ -231,10 +315,11 @@ private:
   std::vector<Reference *> _rel32Candidates;
 
   /// \brief the list of PLT atoms.
-  std::vector<PLTAtom *> _pltVector;
+  std::vector<PLTAtom *> _pltRegVector;
+  std::vector<PLTAtom *> _pltMicroVector;
 
   /// \brief the list of GOTPLT atoms.
-  std::vector<GOTAtom *> _gotpltVector;
+  std::vector<GOTPLTAtom *> _gotpltVector;
 
   /// \brief the list of Object entries.
   std::vector<ObjectAtom *> _objectVector;
@@ -250,8 +335,8 @@ private:
   void collectReferenceInfo(const MipsELFDefinedAtom<ELFT> &atom,
                             Reference &ref);
 
-  void handlePlain(Reference &ref);
-  void handle26(Reference &ref);
+  void handlePlain(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
+  void handle26(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
   void handleGOT(Reference &ref);
   void handleGPRel(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
 
@@ -260,19 +345,26 @@ private:
   const GOTAtom *getTLSGOTEntry(const Atom *a);
   const GOTAtom *getTLSGdGOTEntry(const Atom *a);
   const GOTAtom *getTLSLdmGOTEntry(const Atom *a);
+  const GOTPLTAtom *getGOTPLTEntry(const Atom *a);
   const PLTAtom *getPLTEntry(const Atom *a);
-  const LA25Atom *getLA25Entry(const Atom *a);
+  const PLTAtom *getPLTRegEntry(const Atom *a);
+  const PLTAtom *getPLTMicroEntry(const Atom *a);
+  const LA25Atom *getLA25Entry(const Atom *target, bool isMicroMips);
+  const LA25Atom *getLA25RegEntry(const Atom *a);
+  const LA25Atom *getLA25MicroEntry(const Atom *a);
   const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);
 
+  PLTAtom *createPLTHeader(bool isMicroMips);
+
   bool isLocal(const Atom *a) const;
   bool isLocalCall(const Atom *a) const;
   bool isDynamic(const Atom *atom) const;
   bool requireLA25Stub(const Atom *a) const;
   bool requirePLTEntry(Reference &ref);
   bool requireCopy(Reference &ref);
-  void createPLTHeader();
   bool mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
                       const Reference &ref) const;
+  bool hasPLTEntry(const Atom *atom) const;
 };
 
 template <typename ELFT>
@@ -297,7 +389,7 @@ void RelocationPass<ELFT>::perform(std::
 
   // Create R_MIPS_REL32 relocations.
   for (auto *ref : _rel32Candidates) {
-    if (!isDynamic(ref->target()) || _pltMap.count(ref->target()))
+    if (!isDynamic(ref->target()) || hasPLTEntry(ref->target()))
       continue;
     ref->setKindValue(R_MIPS_REL32);
     if (!isLocalCall(ref->target()))
@@ -321,11 +413,35 @@ void RelocationPass<ELFT>::perform(std::
     mf->addAtom(*got);
   }
 
-  for (auto &plt : _pltVector) {
+  // Create and emit PLT0 entry.
+  PLTAtom *plt0Atom = nullptr;
+  if (!_pltRegVector.empty())
+    plt0Atom = createPLTHeader(false);
+  else if (!_pltMicroVector.empty())
+    plt0Atom = createPLTHeader(true);
+
+  if (plt0Atom) {
+    plt0Atom->setOrdinal(ordinal++);
+    mf->addAtom(*plt0Atom);
+  }
+
+  // Emit regular PLT entries firts.
+  for (auto &plt : _pltRegVector) {
+    plt->setOrdinal(ordinal++);
+    mf->addAtom(*plt);
+  }
+
+  // microMIPS PLT entries come after regular ones.
+  for (auto &plt : _pltMicroVector) {
     plt->setOrdinal(ordinal++);
     mf->addAtom(*plt);
   }
 
+  // Assign PLT0 to GOTPLT entries.
+  assert(_gotpltMap.empty() || plt0Atom);
+  for (auto &a: _gotpltMap)
+    a.second->setPLT0(plt0Atom);
+
   for (auto &gotplt : _gotpltVector) {
     gotplt->setOrdinal(ordinal++);
     mf->addAtom(*gotplt);
@@ -355,14 +471,19 @@ void RelocationPass<ELFT>::handleReferen
   case R_MIPS_PC32:
   case R_MIPS_HI16:
   case R_MIPS_LO16:
+  case R_MICROMIPS_HI16:
+  case R_MICROMIPS_LO16:
     // FIXME (simon): Handle dynamic/static linking differently.
-    handlePlain(ref);
+    handlePlain(atom, ref);
     break;
   case R_MIPS_26:
-    handle26(ref);
+  case R_MICROMIPS_26_S1:
+    handle26(atom, ref);
     break;
   case R_MIPS_GOT16:
   case R_MIPS_CALL16:
+  case R_MICROMIPS_GOT16:
+  case R_MICROMIPS_CALL16:
     handleGOT(ref);
     break;
   case R_MIPS_GPREL32:
@@ -370,19 +491,26 @@ void RelocationPass<ELFT>::handleReferen
     break;
   case R_MIPS_TLS_DTPREL_HI16:
   case R_MIPS_TLS_DTPREL_LO16:
+  case R_MICROMIPS_TLS_DTPREL_HI16:
+  case R_MICROMIPS_TLS_DTPREL_LO16:
     ref.setAddend(ref.addend() - atom.file().getDTPOffset());
     break;
   case R_MIPS_TLS_TPREL_HI16:
   case R_MIPS_TLS_TPREL_LO16:
+  case R_MICROMIPS_TLS_TPREL_HI16:
+  case R_MICROMIPS_TLS_TPREL_LO16:
     ref.setAddend(ref.addend() - atom.file().getTPOffset());
     break;
   case R_MIPS_TLS_GD:
+  case R_MICROMIPS_TLS_GD:
     ref.setTarget(getTLSGdGOTEntry(ref.target()));
     break;
   case R_MIPS_TLS_LDM:
+  case R_MICROMIPS_TLS_LDM:
     ref.setTarget(getTLSLdmGOTEntry(ref.target()));
     break;
   case R_MIPS_TLS_GOTTPREL:
+  case R_MICROMIPS_TLS_GOTTPREL:
     ref.setTarget(getTLSGOTEntry(ref.target()));
     break;
   }
@@ -395,6 +523,7 @@ static bool isConstrainSym(const MipsELF
   switch (ref.kindValue()) {
   case R_MIPS_NONE:
   case R_MIPS_JALR:
+  case R_MICROMIPS_JALR:
   case R_MIPS_GPREL32:
     return false;
   default:
@@ -418,7 +547,9 @@ RelocationPass<ELFT>::collectReferenceIn
   else
     _hasStaticRelocations.insert(ref.target());
 
-  if (ref.kindValue() != R_MIPS_CALL16 && ref.kindValue() != R_MIPS_26)
+  if (ref.kindValue() != R_MIPS_CALL16 &&
+      ref.kindValue() != R_MICROMIPS_CALL16 && ref.kindValue() != R_MIPS_26 &&
+      ref.kindValue() != R_MICROMIPS_26_S1)
     _requiresPtrEquality.insert(ref.target());
 }
 
@@ -448,7 +579,8 @@ bool RelocationPass<ELFT>::mightBeDynami
                                           const Reference &ref) const {
   auto refKind = ref.kindValue();
 
-  if (refKind == R_MIPS_CALL16 || refKind == R_MIPS_GOT16)
+  if (refKind == R_MIPS_CALL16 || refKind == R_MIPS_GOT16 ||
+      refKind == R_MICROMIPS_CALL16 || refKind == R_MICROMIPS_GOT16)
     return true;
 
   if (refKind != R_MIPS_32)
@@ -467,6 +599,11 @@ bool RelocationPass<ELFT>::mightBeDynami
 }
 
 template <typename ELFT>
+bool RelocationPass<ELFT>::hasPLTEntry(const Atom *atom) const {
+  return _pltRegMap.count(atom) || _pltMicroMap.count(atom);
+}
+
+template <typename ELFT>
 bool RelocationPass<ELFT>::requirePLTEntry(Reference &ref) {
   if (!_hasStaticRelocations.count(ref.target()))
     return false;
@@ -512,7 +649,40 @@ bool RelocationPass<ELFT>::isDynamic(con
 }
 
 template <typename ELFT>
-void RelocationPass<ELFT>::handlePlain(Reference &ref) {
+static bool isMicroMips(const MipsELFDefinedAtom<ELFT> &atom) {
+  return atom.codeModel() == DefinedAtom::codeMipsMicro ||
+         atom.codeModel() == DefinedAtom::codeMipsMicroPIC;
+}
+
+template <typename ELFT>
+const LA25Atom *RelocationPass<ELFT>::getLA25Entry(const Atom *target,
+                                                   bool isMicroMips) {
+  return isMicroMips ? getLA25MicroEntry(target) : getLA25RegEntry(target);
+}
+
+template <typename ELFT>
+const PLTAtom *RelocationPass<ELFT>::getPLTEntry(const Atom *a) {
+  bool hasMicroCode = _ctx.getMergedELFFlags() & EF_MIPS_MICROMIPS;
+
+  // If file contains microMIPS code try to reuse compressed PLT entry...
+  if (hasMicroCode) {
+    auto microPLT = _pltMicroMap.find(a);
+    if (microPLT != _pltMicroMap.end())
+      return microPLT->second;
+  }
+
+  // ... then try to reuse a regular PLT entry ...
+  auto regPLT = _pltRegMap.find(a);
+  if (regPLT != _pltRegMap.end())
+    return regPLT->second;
+
+  // ... and finally prefer to create new compressed PLT entry.
+  return hasMicroCode ? getPLTMicroEntry(a) : getPLTRegEntry(a);
+}
+
+template <typename ELFT>
+void RelocationPass<ELFT>::handlePlain(const MipsELFDefinedAtom<ELFT> &atom,
+                                       Reference &ref) {
   if (!isDynamic(ref.target()))
       return;
 
@@ -522,17 +692,29 @@ void RelocationPass<ELFT>::handlePlain(R
     ref.setTarget(getObjectEntry(cast<SharedLibraryAtom>(ref.target())));
 }
 
-template <typename ELFT> void RelocationPass<ELFT>::handle26(Reference &ref) {
-  if (ref.kindValue() == R_MIPS_26 && !isLocal(ref.target())) {
-    ref.setKindValue(LLD_R_MIPS_GLOBAL_26);
-
-    if (requireLA25Stub(ref.target()))
-      ref.setTarget(getLA25Entry(ref.target()));
-  }
+template <typename ELFT>
+void RelocationPass<ELFT>::handle26(const MipsELFDefinedAtom<ELFT> &atom,
+                                    Reference &ref) {
+  bool isMicro = ref.kindValue() == R_MICROMIPS_26_S1;
 
   const auto *sla = dyn_cast<SharedLibraryAtom>(ref.target());
   if (sla && sla->type() == SharedLibraryAtom::Type::Code)
-    ref.setTarget(getPLTEntry(ref.target()));
+    ref.setTarget(isMicro ? getPLTMicroEntry(sla) : getPLTRegEntry(sla));
+
+  if (requireLA25Stub(ref.target()))
+    ref.setTarget(getLA25Entry(ref.target(), isMicro));
+
+  if (!isLocal(ref.target()))
+    switch (ref.kindValue()) {
+    case R_MIPS_26:
+      ref.setKindValue(LLD_R_MIPS_GLOBAL_26);
+      break;
+    case R_MICROMIPS_26_S1:
+      ref.setKindValue(LLD_R_MICROMIPS_GLOBAL_26_S1);
+      break;
+    default:
+      llvm_unreachable("Unexpected relocation kind");
+    }
 }
 
 template <typename ELFT> void RelocationPass<ELFT>::handleGOT(Reference &ref) {
@@ -572,6 +754,8 @@ bool RelocationPass<ELFT>::isLocalCall(c
 
 template <typename ELFT>
 bool RelocationPass<ELFT>::requireLA25Stub(const Atom *a) const {
+  if (isLocal(a))
+    return false;
   if (auto *da = dyn_cast<DefinedAtom>(a))
     return static_cast<const MipsELFDefinedAtom<ELFT> *>(da)->file().isPIC();
   return false;
@@ -660,33 +844,57 @@ const GOTAtom *RelocationPass<ELFT>::get
   return _gotLDMEntry;
 }
 
-template <typename ELFT> void RelocationPass<ELFT>::createPLTHeader() {
-  assert(_pltVector.empty() && _gotpltVector.empty());
-
-  auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
-  _gotpltVector.push_back(ga0);
+template <typename ELFT>
+PLTAtom *RelocationPass<ELFT>::createPLTHeader(bool isMicroMips) {
   auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
-  _gotpltVector.push_back(ga1);
+  _gotpltVector.insert(_gotpltVector.begin(), ga1);
+  auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
+  _gotpltVector.insert(_gotpltVector.begin(), ga0);
 
-  auto pa = new (_file._alloc) PLT0Atom(ga0, _file);
-  _pltVector.push_back(pa);
+  if (isMicroMips)
+    return new (_file._alloc) PLT0MicroAtom(ga0, _file);
+  else
+    return new (_file._alloc) PLT0Atom(ga0, _file);
 }
 
 template <typename ELFT>
-const PLTAtom *RelocationPass<ELFT>::getPLTEntry(const Atom *a) {
-  auto plt = _pltMap.find(a);
-  if (plt != _pltMap.end())
+const GOTPLTAtom *RelocationPass<ELFT>::getGOTPLTEntry(const Atom *a) {
+  auto it = _gotpltMap.find(a);
+  if (it != _gotpltMap.end())
+    return it->second;
+
+  auto ga = new (_file._alloc) GOTPLTAtom(a, _file);
+  _gotpltMap[a] = ga;
+  _gotpltVector.push_back(ga);
+  return ga;
+}
+
+template <typename ELFT>
+const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) {
+  auto plt = _pltRegMap.find(a);
+  if (plt != _pltRegMap.end())
     return plt->second;
 
-  if (_pltVector.empty())
-    createPLTHeader();
+  auto pa = new (_file._alloc) PLTAAtom(getGOTPLTEntry(a), _file);
+  _pltRegMap[a] = pa;
+  _pltRegVector.push_back(pa);
 
-  auto ga = new (_file._alloc) GOTPLTAtom(_pltVector.front(), a, _file);
-  _gotpltVector.push_back(ga);
+  // Check that 'a' dynamic symbol table record should point to the PLT.
+  if (_hasStaticRelocations.count(a) && _requiresPtrEquality.count(a))
+    pa->addReferenceELF_Mips(LLD_R_MIPS_STO_PLT, 0, a, 0);
 
-  auto pa = new (_file._alloc) PLTAAtom(ga, _file);
-  _pltMap[a] = pa;
-  _pltVector.push_back(pa);
+  return pa;
+}
+
+template <typename ELFT>
+const PLTAtom *RelocationPass<ELFT>::getPLTMicroEntry(const Atom *a) {
+  auto plt = _pltMicroMap.find(a);
+  if (plt != _pltMicroMap.end())
+    return plt->second;
+
+  auto pa = new (_file._alloc) PLTMicroAtom(getGOTPLTEntry(a), _file);
+  _pltMicroMap[a] = pa;
+  _pltMicroVector.push_back(pa);
 
   // Check that 'a' dynamic symbol table record should point to the PLT.
   if (_hasStaticRelocations.count(a) && _requiresPtrEquality.count(a))
@@ -696,13 +904,26 @@ const PLTAtom *RelocationPass<ELFT>::get
 }
 
 template <typename ELFT>
-const LA25Atom *RelocationPass<ELFT>::getLA25Entry(const Atom *a) {
-  auto la25 = _la25Map.find(a);
-  if (la25 != _la25Map.end())
+const LA25Atom *RelocationPass<ELFT>::getLA25RegEntry(const Atom *a) {
+  auto la25 = _la25RegMap.find(a);
+  if (la25 != _la25RegMap.end())
+    return la25->second;
+
+  auto sa = new (_file._alloc) LA25RegAtom(a, _file);
+  _la25RegMap[a] = sa;
+  _la25Vector.push_back(sa);
+
+  return sa;
+}
+
+template <typename ELFT>
+const LA25Atom *RelocationPass<ELFT>::getLA25MicroEntry(const Atom *a) {
+  auto la25 = _la25MicroMap.find(a);
+  if (la25 != _la25MicroMap.end())
     return la25->second;
 
-  auto sa = new (_file._alloc) LA25Atom(a, _file);
-  _la25Map[a] = sa;
+  auto sa = new (_file._alloc) LA25MicroAtom(a, _file);
+  _la25MicroMap[a] = sa;
   _la25Vector.push_back(sa);
 
   return sa;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Wed Dec 24 15:04:05 2014
@@ -55,6 +55,7 @@ const Registry::KindStrings MipsTargetHa
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_HI16),
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_LO16),
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_STO_PLT),
+  LLD_KIND_STRING_ENTRY(LLD_R_MICROMIPS_GLOBAL_26_S1),
   LLD_KIND_STRING_END
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=224826&r1=224825&r2=224826&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Wed Dec 24 15:04:05 2014
@@ -87,6 +87,10 @@ class MipsTargetHandler final : public D
 public:
   MipsTargetHandler(MipsLinkingContext &ctx);
 
+  const MipsELFFlagsMerger &getELFFlagsMerger() const {
+    return _elfFlagsMerger;
+  }
+
   MipsTargetLayout<Mips32ElELFType> &getTargetLayout() override {
     return *_targetLayout;
   }
@@ -187,9 +191,11 @@ public:
     const auto &pltSection = _targetLayout.getPLTSection();
 
     for (auto &ste : this->_symbolTable) {
-      if (!ste._atom)
+      const Atom *a = ste._atom;
+      if (!a)
         continue;
-      if (auto *layout = pltSection.findPLTLayout(ste._atom)) {
+      if (auto *layout = pltSection.findPLTLayout(a)) {
+        a = layout->_atom;
         // Under some conditions a dynamic symbol table record should hold
         // a symbol value of the corresponding PLT entry. For details look
         // at the PLT entry creation code in the class MipsRelocationPass.
@@ -197,7 +203,9 @@ public:
         assert(!ste._atomLayout);
         ste._symbol.st_value = layout->_virtualAddr;
         ste._symbol.st_other |= ELF::STO_MIPS_PLT;
-      } else if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
+      }
+
+      if (const auto *da = dyn_cast<DefinedAtom>(a)) {
         if (da->codeModel() == DefinedAtom::codeMipsMicro ||
             da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
           // Adjust dynamic microMIPS symbol value. That allows a dynamic

Added: lld/trunk/test/elf/Mips/dynlib-dynsym-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/dynlib-dynsym-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/dynlib-dynsym-micro.test (added)
+++ lld/trunk/test/elf/Mips/dynlib-dynsym-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,208 @@
+# 1. Check sorting of .dynsym content accordingly to .got section
+#    in case of using microMIPS relocations.
+# 2. Check that microMIPS records in a dynamic symbol table have:
+#    - cleared the STO_MIPS_MICROMIPS flag
+#    - adjusted adress
+
+# Build shared library
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec -o %t-so %t.o
+# RUN: llvm-readobj -dyn-symbols %t-so | FileCheck -check-prefix=CHECK-DYN %s
+
+# Build shared library (yaml format)
+# RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec \
+# RUN:     --output-filetype=yaml -o %t-yaml %t.o
+# RUN: FileCheck -check-prefix=CHECK-GOT %s < %t-yaml
+
+# CHECK-DYN: Format: ELF32-mips
+# CHECK-DYN: Arch: mipsel
+# CHECK-DYN: AddressSize: 32bit
+# CHECK-DYN: LoadName:
+# CHECK-DYN: DynamicSymbols [
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: @ (0)
+# CHECK-DYN:     Value: 0x0
+# CHECK-DYN:     Size: 0
+# CHECK-DYN:     Binding: Local (0x0)
+# CHECK-DYN:     Type: None (0x0)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: Undefined (0x0)
+# CHECK-DYN:   }
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: bar@ (5)
+# CHECK-DYN:     Value: 0x139
+# CHECK-DYN:     Size: 4
+# CHECK-DYN:     Binding: Global (0x1)
+# CHECK-DYN:     Type: Function (0x2)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: .text (0x4)
+# CHECK-DYN:   }
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: foo@ (1)
+# CHECK-DYN:     Value: 0x121
+# CHECK-DYN:     Size: 24
+# CHECK-DYN:     Binding: Global (0x1)
+# CHECK-DYN:     Type: Function (0x2)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: .text (0x4)
+# CHECK-DYN:   }
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: ext1@ (9)
+# CHECK-DYN:     Value: 0x0
+# CHECK-DYN:     Size: 0
+# CHECK-DYN:     Binding: Global (0x1)
+# CHECK-DYN:     Type: None (0x0)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: Undefined (0x0)
+# CHECK-DYN:   }
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: ext2@ (14)
+# CHECK-DYN:     Value: 0x0
+# CHECK-DYN:     Size: 0
+# CHECK-DYN:     Binding: Global (0x1)
+# CHECK-DYN:     Type: None (0x0)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: Undefined (0x0)
+# CHECK-DYN:   }
+# CHECK-DYN: ]
+
+# CHECK-GOT:   - type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:   - type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 80 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:   - ref-name:        L002
+# CHECK-GOT:     type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:     references:
+# CHECK-GOT:       - kind:            LLD_R_MIPS_32_HI16
+# CHECK-GOT:         offset:          0
+# CHECK-GOT:         target:          L003
+# CHECK-GOT:   - ref-name:        L004
+# CHECK-GOT:     type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:     references:
+# CHECK-GOT:       - kind:            LLD_R_MIPS_32_HI16
+# CHECK-GOT:         offset:          0
+# CHECK-GOT:         target:          L005
+# CHECK-GOT:   - ref-name:        L006
+# CHECK-GOT:     type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:     references:
+# CHECK-GOT:       - kind:            LLD_R_MIPS_GLOBAL_GOT
+# CHECK-GOT:         offset:          0
+# CHECK-GOT:         target:          foo
+# CHECK-GOT:   - ref-name:        L007
+# CHECK-GOT:     type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:     references:
+# CHECK-GOT:       - kind:            LLD_R_MIPS_GLOBAL_GOT
+# CHECK-GOT:         offset:          0
+# CHECK-GOT:         target:          ext1
+# CHECK-GOT:   - ref-name:        L009
+# CHECK-GOT:     type:            got
+# CHECK-GOT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:     alignment:       2^2
+# CHECK-GOT:     section-choice:  custom-required
+# CHECK-GOT:     section-name:    .got
+# CHECK-GOT:     permissions:     rw-
+# CHECK-GOT:     references:
+# CHECK-GOT:       - kind:            LLD_R_MIPS_GLOBAL_GOT
+# CHECK-GOT:         offset:          0
+# CHECK-GOT:         target:          ext2
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+                     EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x1C
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          .rodata.str1
+        Type:            R_MICROMIPS_GOT16
+      - Offset:          0x04
+        Symbol:          .rodata.str1
+        Type:            R_MICROMIPS_LO16
+      - Offset:          0x08
+        Symbol:          .rodata.str2
+        Type:            R_MICROMIPS_GOT16
+      - Offset:          0x0C
+        Symbol:          .rodata.str2
+        Type:            R_MICROMIPS_LO16
+      - Offset:          0x10
+        Symbol:          foo
+        Type:            R_MICROMIPS_CALL16
+      - Offset:          0x14
+        Symbol:          ext1
+        Type:            R_MICROMIPS_CALL16
+      - Offset:          0x18
+        Symbol:          ext2
+        Type:            R_MICROMIPS_CALL16
+  - Name:            .rodata.str1
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x01
+    Size:            0x05
+  - Name:            .rodata.str2
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x01
+    Size:            0x05
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+    - Name:            .rodata.str1
+      Type:            STT_SECTION
+      Section:         .rodata.str1
+    - Name:            .rodata.str2
+      Type:            STT_SECTION
+      Section:         .rodata.str2
+  Global:
+    - Name:            bar
+      Section:         .text
+      Value:           0x18
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            foo
+      Section:         .text
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            ext1
+    - Name:            ext2
+...

Added: lld/trunk/test/elf/Mips/exe-dynsym-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/exe-dynsym-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/exe-dynsym-micro.test (added)
+++ lld/trunk/test/elf/Mips/exe-dynsym-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,94 @@
+# Check that symbol referenced by an entry in the global part of GOT
+# has a corresponded entry in the .dynsym section. This test covers
+# the case when the GOT entry created because of the R_MICROMIPS_GOT16
+# relocation.
+
+# Build executable
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t.exe %t.o
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK-DYN %s
+
+# Build executabl (yaml format)e
+# RUN: lld -flavor gnu -target mipsel -e glob \
+# RUN:     --output-filetype=yaml -o %t.yaml %t.o
+# RUN: FileCheck -check-prefix=CHECK-GOT %s < %t.yaml
+
+# CHECK-DYN: Format: ELF32-mips
+# CHECK-DYN: Arch: mipsel
+# CHECK-DYN: AddressSize: 32bit
+# CHECK-DYN: LoadName:
+# CHECK-DYN: DynamicSymbols [
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: @ (0)
+# CHECK-DYN:     Value: 0x0
+# CHECK-DYN:     Size: 0
+# CHECK-DYN:     Binding: Local (0x0)
+# CHECK-DYN:     Type: None (0x0)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: Undefined (0x0)
+# CHECK-DYN:   }
+# CHECK-DYN:   Symbol {
+# CHECK-DYN:     Name: weakf@ (1)
+# CHECK-DYN:     Value: 0x0
+# CHECK-DYN:     Size: 0
+# CHECK-DYN:     Binding: Weak (0x2)
+# CHECK-DYN:     Type: None (0x0)
+# CHECK-DYN:     Other: 0
+# CHECK-DYN:     Section: Undefined (0x0)
+# CHECK-DYN:   }
+# CHECK-DYN: ]
+
+# CHECK-GOT: - type:            got
+# CHECK-GOT:   content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:   alignment:       2^2
+# CHECK-GOT:   section-choice:  custom-required
+# CHECK-GOT:   section-name:    .got
+# CHECK-GOT:   permissions:     rw-
+# CHECK-GOT: - type:            got
+# CHECK-GOT:   content:         [ 00, 00, 00, 80 ]
+# CHECK-GOT:   alignment:       2^2
+# CHECK-GOT:   section-choice:  custom-required
+# CHECK-GOT:   section-name:    .got
+# CHECK-GOT:   permissions:     rw-
+# CHECK-GOT: - ref-name:        L000
+# CHECK-GOT:   type:            got
+# CHECK-GOT:   content:         [ 00, 00, 00, 00 ]
+# CHECK-GOT:   alignment:       2^2
+# CHECK-GOT:   section-choice:  custom-required
+# CHECK-GOT:   section-name:    .got
+# CHECK-GOT:   permissions:     rw-
+# CHECK-GOT:   references:
+# CHECK-GOT:     - kind:            LLD_R_MIPS_GLOBAL_GOT
+# CHECK-GOT:       offset:          0
+# CHECK-GOT:       target:          weakf
+
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x10
+    Size:            0x04
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          weakf
+        Type:            R_MICROMIPS_GOT16
+
+Symbols:
+  Global:
+    - Name:            glob
+      Section:         .text
+      Other:           [ STO_MIPS_MICROMIPS ]
+  Weak:
+    - Name:            weakf

Added: lld/trunk/test/elf/Mips/exe-got-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/exe-got-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/exe-got-micro.test (added)
+++ lld/trunk/test/elf/Mips/exe-got-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,115 @@
+# Check that external symbol defined in the executable file
+# and referenced by R_MICROMIPS_CALL16 relocation has a corresponded
+# entry in the local GOT section.
+#
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e glob \
+# RUN:     --output-filetype=yaml -o %t.exe %t-o.o %t.so
+# RUN: FileCheck -check-prefix=GOT %s < %t.exe
+
+# GOT header
+# GOT:   - type:            got
+# GOT:     content:         [ 00, 00, 00, 00 ]
+# GOT:     alignment:       2^2
+# GOT:     section-choice:  custom-required
+# GOT:     section-name:    .got
+# GOT:     permissions:     rw-
+# GOT:   - type:            got
+# GOT:     content:         [ 00, 00, 00, 80 ]
+# GOT:     alignment:       2^2
+# GOT:     section-choice:  custom-required
+# GOT:     section-name:    .got
+# GOT:     permissions:     rw-
+# Local GOT entry for 'glob' symbol
+# GOT:   - ref-name:        L000
+# GOT:     type:            got
+# GOT:     content:         [ 00, 00, 00, 00 ]
+# GOT:     alignment:       2^2
+# GOT:     section-choice:  custom-required
+# GOT:     section-name:    .got
+# GOT:     permissions:     rw-
+# GOT:     references:
+# GOT:       - kind:            R_MIPS_32
+# GOT:         offset:          0
+# GOT:         target:          glob
+# Global GOT entry for 'T1' symbol
+# GOT:   - ref-name:        L001
+# GOT:     type:            got
+# GOT:     content:         [ 00, 00, 00, 00 ]
+# GOT:     alignment:       2^2
+# GOT:     section-choice:  custom-required
+# GOT:     section-name:    .got
+# GOT:     permissions:     rw-
+# GOT:     references:
+# GOT:       - kind:            LLD_R_MIPS_GLOBAL_GOT
+# GOT:         offset:          0
+# GOT:         target:          T1
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x08
+  - Name:          .rel.text
+    Type:          SHT_REL
+    Link:          .symtab
+    AddressAlign:  0x04
+    Info:          .text
+    Relocations:
+      - Offset:    0x00
+        Symbol:    glob
+        Type:      R_MICROMIPS_CALL16
+      - Offset:    0x04
+        Symbol:    T1
+        Type:      R_MICROMIPS_CALL16
+
+Symbols:
+  Local:
+    - Name:        .text
+      Type:        STT_SECTION
+      Section:     .text
+  Global:
+    - Name:        glob
+      Section:     .text
+      Other:       [ STO_MIPS_MICROMIPS ]
+    - Name:        T1
+...

Added: lld/trunk/test/elf/Mips/got16-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/got16-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/got16-micro.test (added)
+++ lld/trunk/test/elf/Mips/got16-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,165 @@
+# REQUIRES: mips
+
+# Check handling of global/local R_MICROMIPS_GOT16 relocations.
+# RUN: llvm-mc -triple=mipsel -mattr=micromips -relocation-model=pic \
+# RUN:     -filetype=obj -o=%t.o %s
+# RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec \
+# RUN:     --output-filetype=yaml %t.o \
+# RUN:     | FileCheck -check-prefix YAML %s
+# RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec -o %t2 %t.o
+# RUN: llvm-objdump -t -disassemble -mattr=micromips %t2 \
+# RUN:   | FileCheck -check-prefix RAW %s
+
+# Local GOT entries:
+# YAML:       - ref-name:        L002
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_32_HI16
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          data_1
+# YAML-NEXT:  - ref-name:        L003
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_32_HI16
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          data_2
+# YAML-NEXT:  - ref-name:        L004
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            R_MIPS_32
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          data_h
+
+# Global GOT entries:
+# YAML-NEXT:  - ref-name:        L005
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_GLOBAL_GOT
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          bar
+# YAML-NEXT:      - kind:            R_MIPS_32
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          bar
+# YAML-NEXT:  - ref-name:        L006
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_GLOBAL_GOT
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          foo
+
+# Function glob
+# YAML:      - name:         main
+# YAML-NEXT:   scope:        global
+# YAML-NEXT:   content:      [ 5C, FC, 00, 00, 42, 30, 00, 00, 5C, FC, 00, 00,
+# YAML-NEXT:                   42, 30, 00, 00, 5C, FC, 00, 00, 5C, FC, 00, 00,
+# YAML-NEXT:                   5C, FC, 00, 00 ]
+# YAML-NEXT:   alignment:    4 mod 2^4
+# YAML-NEXT:   code-model:   mips-micro
+# YAML-NEXT:   references:
+# YAML-NEXT:     - kind:         R_MICROMIPS_GOT16
+# YAML-NEXT:       offset:       0
+# YAML-NEXT:       target:       L002
+# YAML-NEXT:     - kind:         R_MICROMIPS_LO16
+# YAML-NEXT:       offset:       4
+# YAML-NEXT:       target:       data_1
+# YAML-NEXT:     - kind:         R_MICROMIPS_GOT16
+# YAML-NEXT:       offset:       8
+# YAML-NEXT:       target:       L003
+# YAML-NEXT:     - kind:         R_MICROMIPS_LO16
+# YAML-NEXT:       offset:       12
+# YAML-NEXT:       target:       data_2
+# YAML-NEXT:     - kind:         R_MICROMIPS_GOT16
+# YAML-NEXT:       offset:       16
+# YAML-NEXT:       target:       L004
+# YAML-NEXT:     - kind:         R_MICROMIPS_CALL16
+# YAML-NEXT:       offset:       20
+# YAML-NEXT:       target:       L005
+# YAML-NEXT:     - kind:         R_MICROMIPS_CALL16
+# YAML-NEXT:       offset:       24
+# YAML-NEXT:       target:       L006
+
+# RAW: Disassembly of section .text:
+# RAW: main:
+# RAW-NEXT:   164:  5c fc 18 80   lw      $2, -32744($gp)
+# RAW-NEXT:   168:  42 30 40 10   addiu   $2, $2, 4160
+# RAW-NEXT:   16c:  5c fc 1c 80   lw      $2, -32740($gp)
+# RAW-NEXT:   170:  42 30 60 20   addiu   $2, $2, 8288
+# RAW-NEXT:   174:  5c fc 20 80   lw      $2, -32736($gp)
+# RAW-NEXT:   178:  5c fc 24 80   lw      $2, -32732($gp)
+# RAW-NEXT:   17c:  5c fc 28 80   lw      $2, -32728($gp)
+
+# RAW: SYMBOL TABLE:
+# RAW: 00000000       *UND*  00000000
+# RAW: 00001040 l     .data  00000000 data_1
+# RAW: 00002060 l     .data  00000001 data_2
+# RAW: 00000160 g   F .text  00000004 bar
+# RAW: 00000164 g   F .text  0000001c main
+# RAW: 00002061 g     .data  00000001 data_h
+
+        .data
+        .type   data_1, @object
+        .size   data_1, 4128
+data_1:
+        .byte   1
+        .space  4127
+        .type   data_2, @object
+        .size   data_2, 1
+data_2:
+        .byte   2
+        .hidden data_h
+        .globl  data_h
+        .type   data_h, @object
+        .size   data_h, 1
+data_h:
+        .byte   3
+
+        .text
+        .globl  bar
+        .set    micromips
+        .ent    bar
+        .type   bar, @function
+bar:
+        nop
+        .end    bar
+        .size   bar, .-bar
+
+        .globl  main
+        .set    micromips
+        .ent    main
+        .type   main, @function
+main:
+        lw      $2,%got(data_1)($28)
+        addiu   $2,$2,%lo(data_1)
+        lw      $2,%got(data_2)($28)
+        addiu   $2,$2,%lo(data_2)
+        lw      $2,%got(data_h)($28)
+        lw      $2,%call16(bar)($28)
+        lw      $2,%call16(foo)($28)
+
+        .end    main
+        .size   main, .-main

Added: lld/trunk/test/elf/Mips/gp-sym-1-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/gp-sym-1-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/gp-sym-1-micro.test (added)
+++ lld/trunk/test/elf/Mips/gp-sym-1-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,88 @@
+# Check that microMIPS relocations against __gnu_local_gp
+# use "gp" value as target.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
+# RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=SEC %s
+
+# SYM:      Name: _gp (203)
+# SYM-NEXT: Value: 0x408FF0
+
+# SEC:      Contents of section .text:
+# SEC-NEXT:  400184 00004100 0000f08f 2000bc00  ..A..... ...
+# SEC:      Contents of section .got:
+# SEC-NEXT:  401000 00000000 00000080           ........
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            12
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          __gnu_local_gp
+        Type:            R_MICROMIPS_HI16
+      - Offset:          0x04
+        Symbol:          __gnu_local_gp
+        Type:            R_MICROMIPS_LO16
+      - Offset:          0x08
+        Symbol:          T1
+        Type:            R_MICROMIPS_26_S1
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+  Global:
+    - Name:            T0
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x08
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            __gnu_local_gp
+    - Name:            T1
+...

Added: lld/trunk/test/elf/Mips/hilo16-8-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/hilo16-8-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/hilo16-8-micro.test (added)
+++ lld/trunk/test/elf/Mips/hilo16-8-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,81 @@
+# REQUIRES: mips
+
+# Check calculation of AHL addendums for R_MICROMIPS_HI16 / R_MICROMIPS_LO16
+# relocations for a regular symbol.
+#
+# RUN: llvm-mc -triple=mipsel -mattr=micromips -filetype=obj -o=%t-obj %s
+# RUN: lld -flavor gnu -target mipsel -e glob1 -o %t-exe %t-obj
+# RUN: llvm-objdump -t -d -mattr=micromips %t-exe | FileCheck %s
+
+# CHECK:      Disassembly of section .text:
+# CHECK-NEXT: glob1:
+# CHECK-NEXT:   400130:   a8 41 40 00   lui   $8, 64
+# CHECK-NEXT:   400134:   08 3d 6a 01   lh    $8, 362($8)
+# CHECK-NEXT:   400138:   a8 41 41 00   lui   $8, 65
+# CHECK-NEXT:   40013c:   08 3d 68 81   lh    $8, -32408($8)
+# CHECK-NEXT:   400140:   a8 41 41 00   lui   $8, 65
+# CHECK-NEXT:   400144:   08 3d e9 81   lh    $8, -32279($8)
+# CHECK-NEXT:   400148:   a8 41 42 00   lui   $8, 66
+# CHECK-NEXT:   40014c:   08 3d 69 81   lh    $8, -32407($8)
+# CHECK-NEXT:   400150:   a8 41 40 40   lui   $8, 16448
+# CHECK-NEXT:   400154:   08 3d 69 01   lh    $8, 361($8)
+# CHECK-NEXT:   400158:   a8 41 40 80   lui   $8, 32832
+# CHECK-NEXT:   40015c:   08 3d 69 01   lh    $8, 361($8)
+# CHECK-NEXT:   400160:   a8 41 c1 80   lui   $8, 32961
+# CHECK-NEXT:   400164:   08 3d e9 81   lh    $8, -32279($8)
+
+# CHECK:      glob2:
+# CHECK-NEXT:   400168:   a8 41 40 00   lui   $8, 64
+# CHECK-NEXT:   40016c:   a8 41 40 00   lui   $8, 64
+# CHECK-NEXT:   400170:   a8 41 41 00   lui   $8, 65
+# CHECK-NEXT:   400174:   a8 41 42 00   lui   $8, 66
+# CHECK-NEXT:   400178:   a8 41 40 40   lui   $8, 16448
+# CHECK-NEXT:   40017c:   a8 41 40 80   lui   $8, 32832
+# CHECK-NEXT:   400180:   a8 41 c1 80   lui   $8, 32961
+# CHECK-NEXT:   400184:   08 3d b1 81   lh    $8, -32335($8)
+
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400130 g F .text 00000038 glob1
+# CHECK: 00400168 g F .text 00000020 glob2
+
+    .globl glob1
+    .type  glob1, @function
+    .set   micromips
+    .ent   glob1
+glob1:
+    lui     $t0,%hi(glob2+0x00000001)
+    lh      $t0,%lo(glob2+0x00000001)($t0)
+
+    lui     $t0,%hi(glob2+0x00007fff)
+    lh      $t0,%lo(glob2+0x00007fff)($t0)
+
+    lui     $t0,%hi(glob2+0x00008080)
+    lh      $t0,%lo(glob2+0x00008080)($t0)
+
+    lui     $t0,%hi(glob2+0x00018000)
+    lh      $t0,%lo(glob2+0x00018000)($t0)
+
+    lui     $t0,%hi(glob2+0x40000000)
+    lh      $t0,%lo(glob2+0x40000000)($t0)
+
+    lui     $t0,%hi(glob2+0x80000000)
+    lh      $t0,%lo(glob2+0x80000000)($t0)
+
+    lui     $t0,%hi(glob2+0x80808080)
+    lh      $t0,%lo(glob2+0x80808080)($t0)
+    .end    glob1
+
+    .globl glob2
+    .type  glob2, @function
+    .set   micromips
+    .ent   glob2
+glob2:
+    lui     $t0,%hi(glob1+0x00000001)
+    lui     $t0,%hi(glob1+0x00007fff)
+    lui     $t0,%hi(glob1+0x00008080)
+    lui     $t0,%hi(glob1+0x00018000)
+    lui     $t0,%hi(glob1+0x40000000)
+    lui     $t0,%hi(glob1+0x80000000)
+    lui     $t0,%hi(glob1+0x80808080)
+    lh      $t0,%lo(glob1+0x80808080)($t0)
+    .end    glob2

Added: lld/trunk/test/elf/Mips/hilo16-9-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/hilo16-9-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/hilo16-9-micro.test (added)
+++ lld/trunk/test/elf/Mips/hilo16-9-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,68 @@
+# REQUIRES: mips
+
+# Check calculation of AHL addendums for R_MICROMIPS_HI16 / R_MICROMIPS_LO16
+# relocations for the _gp_disp symbol.
+#
+# RUN: llvm-mc -triple=mipsel -mattr=micromips -filetype=obj -o=%t-obj %s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t-so %t-obj
+# RUN: llvm-objdump -t -d -mattr=micromips %t-so | FileCheck %s
+
+# CHECK:      Disassembly of section .text:
+# CHECK-NEXT: glob1:
+# CHECK-NEXT:      130:   a8 41 01 00   lui   $8, 1
+# CHECK-NEXT:      134:   08 3d c0 9e   lh    $8, -24896($8)
+# CHECK-NEXT:      138:   a8 41 01 00   lui   $8, 1
+# CHECK-NEXT:      13c:   08 3d b6 1e   lh    $8, 7862($8)
+# CHECK-NEXT:      140:   a8 41 01 00   lui   $8, 1
+# CHECK-NEXT:      144:   08 3d 2f 1f   lh    $8, 7983($8)
+# CHECK-NEXT:      148:   a8 41 02 00   lui   $8, 2
+# CHECK-NEXT:      14c:   08 3d a7 1e   lh    $8, 7847($8)
+# CHECK-NEXT:      150:   a8 41 01 40   lui   $8, 16385
+# CHECK-NEXT:      154:   08 3d 9f 9e   lh    $8, -24929($8)
+
+# CHECK:      glob2:
+# CHECK-NEXT:      158:   a8 41 01 00   lui   $8, 1
+# CHECK-NEXT:      15c:   a8 41 01 00   lui   $8, 1
+# CHECK-NEXT:      160:   a8 41 02 00   lui   $8, 2
+# CHECK-NEXT:      164:   a8 41 03 00   lui   $8, 3
+# CHECK-NEXT:      168:   a8 41 01 40   lui   $8, 16385
+# CHECK-NEXT:      16c:   08 3d 87 9e   lh    $8, -24953($8)
+
+# CHECK: SYMBOL TABLE:
+# CHECK: 00000130 g F .text 00000028 glob1
+# CHECK: 00000158 g F .text 00000018 glob2
+# CHECK: 00009ff0 g   *ABS* 00000000 _gp_disp
+
+    .globl glob1
+    .type  glob1, @function
+    .set   micromips
+    .ent   glob1
+glob1:
+    lui     $t0,%hi(_gp_disp+0x00000001)
+    lh      $t0,%lo(_gp_disp+0x00000001)($t0)
+
+    lui     $t0,%hi(_gp_disp+0x00007fff)
+    lh      $t0,%lo(_gp_disp+0x00007fff)($t0)
+
+    lui     $t0,%hi(_gp_disp+0x00008080)
+    lh      $t0,%lo(_gp_disp+0x00008080)($t0)
+
+    lui     $t0,%hi(_gp_disp+0x00018000)
+    lh      $t0,%lo(_gp_disp+0x00018000)($t0)
+
+    lui     $t0,%hi(_gp_disp+0x40000000)
+    lh      $t0,%lo(_gp_disp+0x40000000)($t0)
+    .end    glob1
+
+    .globl glob2
+    .type  glob2, @function
+    .set   micromips
+    .ent   glob2
+glob2:
+    lui     $t0,%hi(_gp_disp+0x00000001)
+    lui     $t0,%hi(_gp_disp+0x00007fff)
+    lui     $t0,%hi(_gp_disp+0x00008080)
+    lui     $t0,%hi(_gp_disp+0x00018000)
+    lui     $t0,%hi(_gp_disp+0x40000000)
+    lh      $t0,%lo(_gp_disp+0x40000000)($t0)
+    .end    glob2

Added: lld/trunk/test/elf/Mips/jalx-align-err.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/jalx-align-err.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/jalx-align-err.test (added)
+++ lld/trunk/test/elf/Mips/jalx-align-err.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,45 @@
+# Check that LLD shows an error if jalx target value is not word-aligned.
+
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t-exe %t-obj 2>&1 | FileCheck %s
+
+# CHECK: The jalx target 0x00400116 is not word-aligned.
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+             EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         8
+  AddressAlign: 16
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0
+      Symbol: T1
+      Type:   R_MICROMIPS_26_S1
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   6
+      Size:    2

Added: lld/trunk/test/elf/Mips/jalx-bit-err.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/jalx-bit-err.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/jalx-bit-err.test (added)
+++ lld/trunk/test/elf/Mips/jalx-bit-err.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,48 @@
+# Check that LLD shows an error if jalx target value has incorrect 0 bit.
+
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t-exe %t-obj 2>&1 | FileCheck %s
+
+# CHECK: Incorrect bit 0 for the jalx target 0x00400115.
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+             EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         8
+  AddressAlign: 16
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0
+      Symbol: T1
+      Type:   R_MICROMIPS_26_S1
+    - Offset: 5
+      Symbol: T0
+      Type:   R_MIPS_26
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   5
+      Size:    3

Added: lld/trunk/test/elf/Mips/jump-fix-err.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/jump-fix-err.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/jump-fix-err.test (added)
+++ lld/trunk/test/elf/Mips/jump-fix-err.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,45 @@
+# Check that LLD shows an error in case
+# of replacing an unknown unstruction by jalx.
+
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel -o %t-exe %t-obj 2>&1 | FileCheck %s
+
+# CHECK: Unsupported jump opcode (0x00) for ISA modes cross call.
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+             EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         8
+  AddressAlign: 16
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0
+      Symbol: T0
+      Type:   R_MICROMIPS_26_S1
+
+Symbols:
+  Global:
+    - Name:    __start
+      Section: .text
+      Type:    STT_FUNC
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   4
+      Size:    4

Added: lld/trunk/test/elf/Mips/la25-stub-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/la25-stub-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/la25-stub-micro.test (added)
+++ lld/trunk/test/elf/Mips/la25-stub-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,138 @@
+# Check microMIPS LA25 stubs creation when PIC code
+# is called from non-PIC routines.
+
+# Build executable from pic and non-pic code.
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-npic.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-pic.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-main.o
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t.exe \
+# RUN:         %t-npic.o %t-pic.o %t-main.o
+
+# RUN: llvm-readobj -t %t.exe | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=ASM %s
+
+# SYM:      Name: loc (13)
+# SYM-NEXT: Value: 0x400135
+# SYM:      Name: T1N (1)
+# SYM-NEXT: Value: 0x400111
+# SYM:      Name: T1 (5)
+# SYM-NEXT: Value: 0x400121
+# SYM:      Name: glob (8)
+# SYM-NEXT: Value: 0x400125
+
+# ASM:      Contents of section .text:
+# ASM-NEXT:  400110 00000000 00000000 00000000 00000000
+# ASM-NEXT:  400120 00000000 00000000 00000000 10f04900
+#      0x100049 << 2 == 0x400125 (jalx glob) --^
+# ASM-NEXT:  400130 00000000 20f49200 00000000 20f48800
+#                            ^-- 0x100049 << 2 == 0x400124 (jal glob)
+#        0x100044 << 2 == 0x400110 (jal T1N) --^
+# ASM-NEXT:  400140 00000000 20f4a800 00000000 00000000
+#                            ^-- 0x100054 << 2 == 0x400150 (jal T1 stub)
+# ASM-NEXT:  400150 b9414000 20d49000 39332101 00000000
+#                            ^-- j 0x400120 (T1)
+
+# npic.o
+---
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [ EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+              EF_MIPS_CPIC, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x04
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1N
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+
+# pic.o
+---
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [ EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+              EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x04
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+
+# main.o
+---
+FileHeader:
+  Class:     ELFCLASS32
+  Data:      ELFDATA2LSB
+  Type:      ET_REL
+  Machine:   EM_MIPS
+  Flags:     [ EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+               EF_MIPS_CPIC, EF_MIPS_MICROMIPS ]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Content:         '000000000000000000f400000000000000f400000000000000f400000000000000f4000000000000'
+#                                       jal loc         jal glob        jal T1N         jal T1
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x08
+        Symbol:          .text
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x10
+        Symbol:          glob
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x18
+        Symbol:          T1N
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x20
+        Symbol:          T1
+        Type:            R_MICROMIPS_26_S1
+
+Symbols:
+  Local:
+    - Name:    loc
+      Section: .text
+      Value:   0x10
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    .text
+      Type:    STT_SECTION
+      Section: .text
+  Global:
+    - Name:    glob
+      Section: .text
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    T1
+    - Name:    T1N
+...

Added: lld/trunk/test/elf/Mips/pc23-range.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/pc23-range.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/pc23-range.test (added)
+++ lld/trunk/test/elf/Mips/pc23-range.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,57 @@
+# Check that LLD shows an error if ADDIUPC immediate is out of range.
+
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: env LLD_RUN_ROUNDTRIP_TEST= \
+# RUN:   lld -flavor gnu -target mipsel -o %t-exe %t-obj 2>&1 | FileCheck %s
+
+# CHECK: The addiupc instruction immediate 0x02000008 is out of range
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+             EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Content:      "0000000080780100"
+#                        ^ PC23: 1 << 2 = 4 => T0 + 4 - 4 = T0
+  AddressAlign: 16
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Flags:        [ SHF_ALLOC ]
+  AddressAlign: 0x04
+  Size:         0x4000000
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 4
+      Symbol: T0
+      Type:   R_MICROMIPS_PC23_S2
+
+Symbols:
+  Global:
+    - Name:    __start
+      Section: .text
+      Type:    STT_FUNC
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    TZ
+      Section: .data
+      Type:    STT_FUNC
+      Value:   0
+      Size:    0x2000000
+    - Name:    T0
+      Section: .data
+      Type:    STT_FUNC
+      Value:   0x2000000
+      Size:    4

Added: lld/trunk/test/elf/Mips/plt-entry-mixed-1.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-entry-mixed-1.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/plt-entry-mixed-1.test (added)
+++ lld/trunk/test/elf/Mips/plt-entry-mixed-1.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,114 @@
+# REQUIRES: mips
+
+# Conditions:
+# a) Object file contains both R_MIPS_26 and microMIPS non-jal relocations.
+# b) The R_MIPS_26 relocation handled first.
+# Check:
+# a) PLT contains the only regular entry.
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t.so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t.o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o.o %t.so
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+
+# CHECK:      Disassembly of section .plt:
+# CHECK-NEXT: .plt:
+# CHECK-NEXT:   400170:   40 00 1c 3c   lui     $gp, 64
+# CHECK-NEXT:   400174:   00 20 99 8f   lw      $25, 8192($gp)
+# CHECK-NEXT:   400178:   00 20 9c 27   addiu   $gp, $gp, 8192
+# CHECK-NEXT:   40017c:   23 c0 1c 03   subu    $24, $24, $gp
+# CHECK-NEXT:   400180:   21 78 e0 03   move    $15, $ra
+# CHECK-NEXT:   400184:   82 c0 18 00   srl     $24, $24, 2
+# CHECK-NEXT:   400188:   09 f8 20 03   jalr    $25
+# CHECK-NEXT:   40018c:   fe ff 18 27   addiu   $24, $24, -2
+# CHECK-NEXT:   400190:   40 00 0f 3c   lui     $15, 64
+# CHECK-NEXT:   400194:   08 20 f9 8d   lw      $25, 8200($15)
+# CHECK-NEXT:   400198:   08 00 20 03   jr      $25
+# CHECK-NEXT:   40019c:   08 20 f8 25   addiu   $24, $15, 8200
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Content:      "0000000C00000000"
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+- Name:         .rel.text
+  Type:         SHT_REL
+  Info:         .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x0
+      Symbol: T1
+      Type:   R_MIPS_26
+
+- Name:         .rel.data
+  Type:         SHT_REL
+  Info:         .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: T1
+      Type:   R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: T1
+      Type:   R_MICROMIPS_LO16
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    0x8
+    - Name:    D0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x0
+      Size:    8
+    - Name:    T1
+...

Added: lld/trunk/test/elf/Mips/plt-entry-mixed-2.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-entry-mixed-2.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/plt-entry-mixed-2.test (added)
+++ lld/trunk/test/elf/Mips/plt-entry-mixed-2.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,93 @@
+# REQUIRES: mips
+
+# Conditions:
+# a) Object file contains both R_MIPS_26 and R_MICROMIPS_26_S1 relocations.
+# Check:
+# a) PLT contains both regular and compressed PLT entries
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t.so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t.o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o.o %t.so
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+
+# CHECK: Contents of section .plt:
+# CHECK-NEXT:  400170 40001c3c 0020998f 00209c27 23c01c03  @..<. ... .'#...
+# CHECK-NEXT:  400180 2178e003 82c01800 09f82003 feff1827  !x........ ....'
+# CHECK-NEXT:  400190 40000f3c 0820f98d 08002003 0820f825  @..<. .... .. .%
+# CHECK-NEXT:  4001a0 00799a07 22ff0000 9945020f           .y.."....E..
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T2
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Content:      "0000000C000000000000000000000000"
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .rel.text
+  Type:         SHT_REL
+  Info:         .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x0
+      Symbol: T2
+      Type:   R_MIPS_26
+    - Offset: 0x8
+      Symbol: T2
+      Type:   R_MICROMIPS_26_S1
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    0x8
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x8
+      Size:    0x8
+      Other:   [STO_MIPS_MICROMIPS]
+    - Name:    T2
+...

Added: lld/trunk/test/elf/Mips/plt-entry-mixed-3.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-entry-mixed-3.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/plt-entry-mixed-3.test (added)
+++ lld/trunk/test/elf/Mips/plt-entry-mixed-3.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,98 @@
+# REQUIRES: mips
+
+# Conditions:
+# a) Object file contains microMIPS instructions.
+# b) There is a relocation refers arbitrary symbols and requires a PLT entry.
+# Check:
+# a) PLT contains a compressed entry.
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t.so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t.o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o.o %t.so
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+
+# CHECK: Contents of section .plt:
+# CHECK-NEXT:  400170 8079a407 23ff0000 35052525 0233feff  .y..#...5.%%.3..
+# CHECK-NEXT:  400180 ff0df945 830f000c 0079a007 22ff0000  ...E.....y.."...
+# CHECK-NEXT:  400190 9945020f                             .E..
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         16
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+- Name:         .rel.data
+  Type:         SHT_REL
+  Info:         .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: T1
+      Type:   R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: T1
+      Type:   R_MICROMIPS_LO16
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    16
+    - Name:    D0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x0
+      Size:    8
+    - Name:    T1
+...

Added: lld/trunk/test/elf/Mips/plt-entry-mixed-4.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-entry-mixed-4.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/plt-entry-mixed-4.test (added)
+++ lld/trunk/test/elf/Mips/plt-entry-mixed-4.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,85 @@
+# REQUIRES: mips
+
+# Conditions:
+# a) Object file contains R_MIPS_26 relocation refers to the microMIPS symbol.
+# Check:
+# a) PLT contains a regular non-compressed entry.
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t.so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t.o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o.o %t.so
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+
+# CHECK: Contents of section .plt:
+# CHECK-NEXT:  400170 40001c3c 0020998f 00209c27 23c01c03  @..<. ... .'#...
+# CHECK-NEXT:  400180 2178e003 82c01800 09f82003 feff1827  !x........ ....'
+# CHECK-NEXT:  400190 40000f3c 0820f98d 08002003 0820f825  @..<. .... .. .%
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+      Other:   [STO_MIPS_MICROMIPS]
+
+# o.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Content:      "0000000C00000000"
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .rel.text
+  Type:         SHT_REL
+  Info:         .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x0
+      Symbol: T1
+      Type:   R_MIPS_26
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    0x8
+    - Name:    T1
+...

Added: lld/trunk/test/elf/Mips/plt-header-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-header-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/plt-header-micro.test (added)
+++ lld/trunk/test/elf/Mips/plt-header-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,109 @@
+# REQUIRES: mips
+
+# Check initialization of .plt header entries
+# if all PLT entries use microMIPS encoding.
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t.exe %t-o.o %t.so
+# RUN: llvm-objdump -section-headers -s %t.exe | \
+# RUN:   FileCheck -check-prefix=EXE %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+# DIS: Disassembly of section .plt:
+# DIS: .plt:
+# DIS-NEXT:   400170:  7980 07a4    addiu   v1,$pc,7824
+# DIS-NEXT:   400174:  ff23 0000    lw      t9,0(v1)
+# DIS-NEXT:   400178:  0535         subu    v0,v0,v1
+# DIS-NEXT:   40017a:  2525         srl     v0,v0,2
+# DIS-NEXT:   40017c:  3302 fffe    addiu   t8,v0,-2
+# DIS-NEXT:   400180:  0dff         move    t7,ra
+# DIS-NEXT:   400182:  45f9         jalrs   t9
+# DIS-NEXT:   400184:  0f83         move    gp,v1
+# DIS-NEXT:   400186:  0c00         nop
+
+# EXE: Sections:
+# EXE: Idx Name          Size      Address          Type
+# EXE:   6 .plt          00000024 0000000000400170 TEXT DATA
+# EXE:  10 .got.plt      0000000c 0000000000402000 DATA
+
+# EXE: Contents of section .plt:
+# EXE-NEXT: 400170 8079a407 23ff0000 35052525 0233feff  .y..#...5.%%.3..
+# EXE-NEXT: 400180 ff0df945 830f000c 0079a007 22ff0000  ...E.....y.."...
+# EXE-NEXT: 400190 9945020f
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x20
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x08
+        Symbol:          .text
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x10
+        Symbol:          glob
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x18
+        Symbol:          T1
+        Type:            R_MICROMIPS_26_S1
+
+Symbols:
+  Local:
+    - Name:            loc
+      Section:         .text
+      Value:           0x10
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+  Global:
+    - Name:            glob
+      Section:         .text
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            T1
+...

Added: lld/trunk/test/elf/Mips/plt-header-mixed.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-header-mixed.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/plt-header-mixed.test (added)
+++ lld/trunk/test/elf/Mips/plt-header-mixed.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,118 @@
+# REQUIRES: mips
+
+# Check initialization of .plt header entries if there are both regular
+# and microMIPS encoded PLT entries. Check that R_MIPS_26 and R_MICROMIPS_26_S1
+# relocation with the same target cause generation of two distinct PLT entries.
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e globR -o %t.exe %t-o.o %t.so
+# RUN: llvm-objdump -section-headers -s %t.exe | \
+# RUN:   FileCheck -check-prefix=EXE %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+# DIS: Disassembly of section .plt:
+# DIS: .plt:
+# PLT0
+# DIS-NEXT:   400170:   3c1c0040    lui     gp,0x40
+# DIS-NEXT:   400174:   8f992000    lw      t9,8192(gp)
+# DIS-NEXT:   400178:   279c2000    addiu   gp,gp,8192
+# DIS-NEXT:   40017c:   031cc023    subu    t8,t8,gp
+# DIS-NEXT:   400180:   03e07821    move    t7,ra
+# DIS-NEXT:   400184:   0018c082    srl     t8,t8,0x2
+# DIS-NEXT:   400188:   0320f809    jalr    t9
+# DIS-NEXT:   40018c:   2718fffe    addiu   t8,t8,-2
+
+# T1 at plt
+# DIS-NEXT:   400190:   3c0f0040    lui     t7,0x40
+# DIS-NEXT:   400194:   8df92008    lw      t9,8200(t7)
+# DIS-NEXT:   400198:   03200008    jr      t9
+# DIS-NEXT:   40019c:   25f82008    addiu   t8,t7,8200
+
+# T1 at micromipsplt
+# DIS-NEXT:   4001a0:   7900 079a   addiu   v0,$pc,7784
+# DIS-NEXT:   4001a4:   ff22 0000   lw      t9,0(v0)
+# DIS-NEXT:   4001a8:   4599        jr      t9
+# DIS-NEXT:   4001aa:   0f02        move    t8,v0
+
+# EXE: Sections:
+# EXE: Idx Name          Size      Address          Type
+# EXE:   6 .plt          0000003c 0000000000400170 TEXT DATA
+# EXE:  10 .got.plt      0000000c 0000000000402000 DATA
+
+# EXE: Contents of section .plt:
+# EXE-NEXT: 400170 40001c3c 0020998f 00209c27 23c01c03  @..<. ... .'#...
+# EXE-NEXT: 400180 2178e003 82c01800 09f82003 feff1827  !x........ ....'
+# EXE-NEXT: 400190 40000f3c 0820f98d 08002003 0820f825  @..<. .... .. .%
+# EXE-NEXT: 4001a0 00799a07 22ff0000 9945020f           .y.."....E..
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Size:         0x0C
+    AddressAlign: 16
+    Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x8
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x0
+        Symbol:          T1
+        Type:            R_MIPS_26
+      - Offset:          0x4
+        Symbol:          T1
+        Type:            R_MICROMIPS_26_S1
+
+Symbols:
+  Global:
+    - Name:            globR
+      Section:         .text
+      Value:           0x0
+      Size:            0x4
+    - Name:            globM
+      Section:         .text
+      Value:           0x4
+      Size:            0x4
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            T1
+...

Added: lld/trunk/test/elf/Mips/r26-1-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/r26-1-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/r26-1-micro.test (added)
+++ lld/trunk/test/elf/Mips/r26-1-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,137 @@
+# REQUIRES: mips
+
+# Check handling of R_MICROMIPS_26_S1 relocation.
+
+# Build shared library
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: llvm-readobj -relocations %t-o.o | \
+# RUN:   FileCheck -check-prefix=OBJ-REL %s
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t.exe %t-o.o %t.so
+# RUN: llvm-objdump -section-headers -s %t.exe | \
+# RUN:   FileCheck -check-prefix=EXE %s
+# RUN: llvm-readobj -relocations %t.exe | FileCheck -check-prefix=EXE-REL %s
+
+# Object file has three R_MICROMIPS_26_S1 relocations
+# OBJ-REL: Relocations [
+# OBJ-REL-NEXT:   Section (2) .rel.text {
+# OBJ-REL-NEXT:      0x8 R_MICROMIPS_26_S1 .text 0x0
+# OBJ-REL-NEXT:     0x10 R_MICROMIPS_26_S1 glob  0x0
+# OBJ-REL-NEXT:     0x18 R_MICROMIPS_26_S1 T1  0x0
+# OBJ-REL-NEXT:   }
+# OBJ-REL-NEXT: ]
+
+# Executable file has the only relocation for external symbol
+# EXE-REL: Relocations [
+# EXE-REL-NEXT:   Section (5) .rel.plt {
+# EXE-REL-NEXT:     0x402008 R_MIPS_JUMP_SLOT T1 0x0
+# EXE-REL-NEXT:   }
+# EXE-REL-NEXT: ]
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+# DIS: Disassembly of section .plt:
+# DIS: .plt:
+# T1 at micromipsplt
+# DIS-NEXT:   400178:   7900 07a4   addiu   v0,$pc,7824
+# DIS-NEXT:   40017c:   ff22 0000   lw      t9,0(v0)
+# DIS-NEXT:   400180:   4599        jr      t9
+# DIS-NEXT:   400182:   0f02        move    t8,v0
+
+# DIS: Disassembly of section .text:
+# DIS: glob:
+# DIS-NEXT:   400184:   f809 0320   sw      zero,800(t1)
+# DIS-NEXT:   400188:   0000 0000   nop
+# DIS-NEXT:   40018c:   0012 0661   0x120661
+# DIS-NEXT:   400182:   0f02        move    t8,v0
+#
+# DIS: loc:
+# DIS-NEXT:   400194:   0020 0cc2   cop2    0x40198
+# DIS-NEXT:   400198:   0000 0000   nop
+# DIS-NEXT:   40019c:   0020 0cbc   mult    $ac0,zero,at
+# DIS-NEXT:   4001a0:   0000 0000   nop
+
+# EXE: Sections:
+# EXE: Idx Name          Size      Address          Type
+# EXE:   6 .plt          00000024 0000000000400160 TEXT DATA
+# EXE:  10 .got.plt      0000000c 0000000000402000 DATA
+
+# EXE: Contents of section .plt:
+# EXE-NEXT:  400160 8079a807 23ff0000 35052525 0233feff  .y..#...5.%%.3..
+# EXE-NEXT:  400170 ff0df945 830f000c 0079a407 22ff0000  ...E.....y.."...
+# EXE-NEXT:  400180 9945020f                             .E..
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+
+# o.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+                     EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Content:         '09F82003000000000400000C000000000000000C000000000000000C00000000'
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x08
+        Symbol:          .text
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x10
+        Symbol:          glob
+        Type:            R_MICROMIPS_26_S1
+      - Offset:          0x18
+        Symbol:          T1
+        Type:            R_MICROMIPS_26_S1
+
+Symbols:
+  Local:
+    - Name:            loc
+      Section:         .text
+      Value:           0x10
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+  Global:
+    - Name:            glob
+      Section:         .text
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            T1
+...

Added: lld/trunk/test/elf/Mips/r26-2-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/r26-2-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/r26-2-micro.test (added)
+++ lld/trunk/test/elf/Mips/r26-2-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,96 @@
+# REQUIRES: mips
+
+# Check reading addendum for R_MICROMIPS_26_S1 relocation.
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel -o %t-exe %t-obj
+# RUN: llvm-objdump -t -s %t-exe | FileCheck %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+# DIS: Disassembly of section .text:
+# DIS-NEXT: __start:
+# DIS-NEXT:   400110:  00 00 00 00   nop
+# DIS-NEXT:   400114:  44 70 10 0c  jal  4309264
+#   0x107044 << 2 = 0x41C110 = _start  + (0x7000 << 2)
+# DIS-NEXT:   400118:  00 00 00 00  nop
+#
+# DIS: loc:
+# DIS-NEXT:   40011c:  47 70 10 0c  jal  4309276
+#   0x107047 << 2 = 0x41C11C = loc  + (0x7000 << 2)
+# DIS-NEXT:   400120:  00 00 00 00  nop
+# DIS-NEXT:   400124:  43 00 10 0c  jal  4194572
+#   0x100043 << 2 = 0x40010C = _start - 4
+# DIS-NEXT:   400128:  00 00 00 00  nop
+# DIS-NEXT:   40012c:  46 00 10 0c  jal  4194584
+#   0x100046 << 2 = 0x400118 = loc - 4
+# DIS-NEXT:   400130:  00 00 00 00  nop
+
+# CHECK: Contents of section .text:
+# CHECK-NEXT:  400110 00000000 20f48ee0 00000000 20f49ae0  .... ....... ...
+# CHECK-NEXT:  400120 00000000 20f48900 00000000 20f49100  .... ....... ...
+# CHECK-NEXT:  400130 00000000                             ....
+
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400124 l  F .text  00000010 loc1
+# CHECK: 00400114 g  F .text  00000010 __start
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+# nop
+# jal __start + 0x1C000
+# nop
+# jal loc + 0x1C000
+# nop
+# jal __start + 7FFFFE2
+# nop
+# jal loc + 7FFFFEA
+# nop
+  Content:  "0000000000f404e00000000000f408e000000000FFF7FFFF00000000FFF7FFFF00000000"
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x4
+      Symbol: __start
+      Type: R_MICROMIPS_26_S1
+    - Offset: 0xC
+      Symbol: loc1
+      Type: R_MICROMIPS_26_S1
+    - Offset: 0x14
+      Symbol: __start
+      Type: R_MICROMIPS_26_S1
+    - Offset: 0x1C
+      Symbol: loc1
+      Type: R_MICROMIPS_26_S1
+
+Symbols:
+  Global:
+    - Name:    __start
+      Section: .text
+      Value:   0x4
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+  Local:
+    - Name:    loc0
+      Section: .text
+      Value:   0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    loc1
+      Section: .text
+      Value:   0x14
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]

Added: lld/trunk/test/elf/Mips/rel-copy-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-copy-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-copy-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-copy-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,159 @@
+# Check R_MIPS_COPY relocation emitting
+# when linking non-shared executable file.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so1.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t1.so %t-so1.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-so2.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t2.so %t-so2.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t1.so %t2.so
+# RUN: llvm-readobj -dt -r -dynamic-table %t.exe | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section (5) .rel.dyn {
+# CHECK-NEXT:     0x402010 R_MIPS_COPY D1 0x0
+# CHECK-NEXT:     0x402018 R_MIPS_COPY D2 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# CHECK:      DynamicSymbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: @ (0)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local (0x0)
+# CHECK-NEXT:     Type: None (0x0)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: D1@ (1)
+# CHECK-NEXT:     Value: 0x402010
+# CHECK-NEXT:     Size: 8
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Object (0x1)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .bss (0xA)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: D2@ (4)
+# CHECK-NEXT:     Value: 0x402018
+# CHECK-NEXT:     Size: 4
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Object (0x1)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .bss (0xA)
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# CHECK:      DynamicSection [ ({{.*}} entries)
+# CHECK:        0x00000001 NEEDED  SharedLibrary (rel-copy-micro.test.tmp1.so)
+# CHECK:        0x00000001 NEEDED  SharedLibrary (rel-copy-micro.test.tmp2.so)
+# CHECK-NEXT:   0x00000000 NULL    0x0
+# CHECK-NEXT: ]
+
+# so1.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: D1
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 4
+
+# so2.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x04
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: D2
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 4
+
+# o.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+- Name: .rel.data
+  Type: SHT_REL
+  Info: .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: D1
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: D1
+      Type: R_MICROMIPS_LO16
+    - Offset: 0x08
+      Symbol: D2
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x08
+      Symbol: D2
+      Type: R_MICROMIPS_LO16
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    D0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x0
+      Size:    8
+    - Name:    D1
+      Type:    STT_OBJECT
+    - Name:    D2
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-01-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-01-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-01-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-01-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,187 @@
+# REQUIRES: mips
+
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) Relocations' targets are symbols defined in the shared object.
+# Check:
+#   a) Emitting R_MIPS_COPY, R_MIPS_JUMP_SLOT relocations.
+#   b) PLT entries creation.
+#   c) STO_MIPS_PLT flag in the dynamic symbol table for symbols require
+#      a pointer equality.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DIS %s
+# RUN: llvm-readobj -dt -r %t.exe | FileCheck -check-prefix=PLT-SYM %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+
+# DIS: Contents of section .plt:
+# DIS-NEXT:  4001b0 80799407 23ff0000 35052525 0233feff  .y..#...5.%%.3..
+# DIS-NEXT:  4001c0 ff0df945 830f000c 00799007 22ff0000  ...E.....y.."...
+# DIS-NEXT:  4001d0 9945020f 00798e07 22ff0000 9945020f  .E...y.."....E..
+
+# PLT-SYM:      Relocations [
+# PLT-SYM-NEXT:   Section (5) .rel.dyn {
+# PLT-SYM-NEXT:     0x402018 R_MIPS_COPY D1 0x0
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT:   Section (6) .rel.plt {
+# PLT-SYM-NEXT:     0x402008 R_MIPS_JUMP_SLOT T3 0x0
+# PLT-SYM-NEXT:     0x40200C R_MIPS_JUMP_SLOT T1 0x0
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT: ]
+
+# PLT-SYM:      DynamicSymbols [
+# PLT-SYM-NEXT:   Symbol {
+# PLT-SYM-NEXT:     Name: @ (0)
+# PLT-SYM-NEXT:     Value: 0x0
+# PLT-SYM-NEXT:     Size: 0
+# PLT-SYM-NEXT:     Binding: Local (0x0)
+# PLT-SYM-NEXT:     Type: None (0x0)
+# PLT-SYM-NEXT:     Other: 0
+# PLT-SYM-NEXT:     Section: Undefined (0x0)
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT:   Symbol {
+# PLT-SYM-NEXT:     Name: D1@ (1)
+# PLT-SYM-NEXT:     Value: 0x402018
+# PLT-SYM-NEXT:     Size: 8
+# PLT-SYM-NEXT:     Binding: Global (0x1)
+# PLT-SYM-NEXT:     Type: Object (0x1)
+# PLT-SYM-NEXT:     Other: 0
+# PLT-SYM-NEXT:     Section: .bss (0xD)
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT:   Symbol {
+# PLT-SYM-NEXT:     Name: T3@ (4)
+# PLT-SYM-NEXT:     Value: 0x0
+# PLT-SYM-NEXT:     Size: 0
+# PLT-SYM-NEXT:     Binding: Global (0x1)
+# PLT-SYM-NEXT:     Type: Function (0x2)
+# PLT-SYM-NEXT:     Other: 0
+# PLT-SYM-NEXT:     Section: Undefined (0x0)
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT:   Symbol {
+# PLT-SYM-NEXT:     Name: T1@ (7)
+# PLT-SYM-NEXT:     Value: 0x4001D5
+# PLT-SYM-NEXT:     Size: 0
+# PLT-SYM-NEXT:     Binding: Global (0x1)
+# PLT-SYM-NEXT:     Type: Function (0x2)
+# PLT-SYM-NEXT:     Other: 8
+# PLT-SYM-NEXT:     Section: Undefined (0x0)
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT: ]
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: T1
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 4
+      Other: [ STO_MIPS_MICROMIPS ]
+    - Name: T3
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x8
+      Size: 4
+      Other: [ STO_MIPS_MICROMIPS ]
+    - Name: D1
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 8
+
+# o.o
+---
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .data
+  Type: SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags: [SHF_WRITE, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x04
+      Symbol: T3
+      Type: R_MICROMIPS_26_S1
+
+- Name: .rel.data
+  Type: SHT_REL
+  Info: .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: T1
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: T1
+      Type: R_MICROMIPS_LO16
+    - Offset: 0x04
+      Symbol: D1
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x04
+      Symbol: D1
+      Type: R_MICROMIPS_LO16
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: T3
+      Type: STT_FUNC
+    - Name: D0
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 8
+    - Name: D1
+      Type: STT_OBJECT
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-03-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-03-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-03-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-03-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,124 @@
+# REQUIRES: mips
+
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) Relocations' target is a symbol defined in the shared object.
+#   c) The target symbol is referenced by both branch (R_MICROMIPS_26_S1)
+#      and regular (R_MIPS_32) relocations.
+# Check:
+#   a) There should be no R_MIPS_REL32 relocation.
+#   b) Linker creates a single PLT entry.
+#   c) STO_MIPS_PLT flag in the dynamic symbol table for symbols require
+#      a pointer equality.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DIS %s
+# RUN: llvm-readobj -dt -r %t.exe | FileCheck -check-prefix=PLT-SYM %s
+
+# FIXME (simon): Check the disassembler output when llvm-objdump starts
+#                to support microMIPS instruction encoding.
+
+# DIS: Contents of section .plt:
+# DIS-NEXT:  400170 8079a407 23ff0000 35052525 0233feff  .y..#...5.%%.3..
+# DIS-NEXT:  400180 ff0df945 830f000c 0079a007 22ff0000  ...E.....y.."...
+# DIS-NEXT:  400190 9945020f                             .E..
+
+# PLT-SYM:      Relocations [
+# PLT-SYM-NEXT:   Section (5) .rel.plt {
+# PLT-SYM-NEXT:     0x402008 R_MIPS_JUMP_SLOT T1 0x0
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT: ]
+
+# PLT-SYM:      Name: T1@ (1)
+# PLT-SYM-NEXT: Value: 0x400189
+# PLT-SYM-NEXT: Size: 0
+# PLT-SYM-NEXT: Binding: Global (0x1)
+# PLT-SYM-NEXT: Type: Function (0x2)
+# PLT-SYM-NEXT: Other: 8
+# PLT-SYM-NEXT: Section: Undefined (0x0)
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+            EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: T1
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 4
+      Other: [ STO_MIPS_MICROMIPS ]
+
+# o.o
+---
+FileHeader: !FileHeader
+  Class: ELFCLASS32
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_MIPS
+  Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Size:  0x08
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .data
+  Type: SHT_PROGBITS
+  Size:  0x08
+  AddressAlign: 16
+  Flags: [SHF_WRITE, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x04
+      Symbol: T1
+      Type: R_MICROMIPS_26_S1
+
+- Name: .rel.data
+  Type: SHT_REL
+  Info: .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x04
+      Symbol: T1
+      Type: R_MIPS_32
+
+Symbols:
+  Global:
+    - Name: T0
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 8
+      Other: [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: D0
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 8
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-04-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-04-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-04-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-04-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,211 @@
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) Relocations' targets are symbols defined in the shared object.
+#   c) Relocations modify a writable section.
+#   d) The first symbol is referenced by R_MIPS32 relocation only
+#   e) The second symbol is referenced by R_MIPS_32
+#      and R_MICROMIPS_26_S1 relocations.
+#   f) The third symbol is referenced by R_MICROMIPS_26_S1
+#      and R_MIPS_32 relocations.
+# Check:
+#   a) There should be the only R_MIPS_REL32 relocation.
+#   b) Linker creates a couple of PLT entry for both symbols referenced
+#      by the R_MICROMIPS_26_S1 branch relocation.
+#   c) STO_MIPS_PLT flag in the dynamic symbol table for symbols require
+#      a pointer equality.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
+# RUN: llvm-readobj -dt -r -s %t.exe | FileCheck -check-prefix=PLT %s
+
+# PLT:      Section {
+# PLT:        Index: 5
+# PLT-NEXT:   Name: .rel.dyn (31)
+# PLT-NEXT:    Type: SHT_REL (0x9)
+# PLT-NEXT:    Flags [ (0x2)
+# PLT-NEXT:      SHF_ALLOC (0x2)
+# PLT-NEXT:    ]
+# PLT-NEXT:    Address: 0x4010A0
+# PLT-NEXT:    Offset: 0x10A0
+# PLT-NEXT:    Size: 8
+# PLT-NEXT:    Link: 3
+# PLT-NEXT:    Info: 0
+# PLT-NEXT:    AddressAlignment: 4
+# PLT-NEXT:    EntrySize: 8
+# PLT-NEXT:  }
+# PLT-NEXT:  Section {
+# PLT-NEXT:    Index: 6
+# PLT-NEXT:    Name: .rel.plt (40)
+# PLT-NEXT:    Type: SHT_REL (0x9)
+# PLT-NEXT:    Flags [ (0x2)
+# PLT-NEXT:      SHF_ALLOC (0x2)
+# PLT-NEXT:    ]
+# PLT-NEXT:    Address: 0x4010A8
+# PLT-NEXT:    Offset: 0x10A8
+# PLT-NEXT:    Size: 16
+# PLT-NEXT:    Link: 3
+# PLT-NEXT:    Info: 0
+# PLT-NEXT:    AddressAlignment: 4
+# PLT-NEXT:    EntrySize: 8
+# PLT-NEXT:  }
+# PLT-NEXT:  Section {
+# PLT-NEXT:    Index: 7
+# PLT-NEXT:    Name: .plt (49)
+# PLT-NEXT:    Type: SHT_PROGBITS (0x1)
+# PLT-NEXT:    Flags [ (0x6)
+# PLT-NEXT:      SHF_ALLOC (0x2)
+# PLT-NEXT:      SHF_EXECINSTR (0x4)
+# PLT-NEXT:    ]
+# PLT-NEXT:    Address: 0x4010C0
+# PLT-NEXT:    Offset: 0x10C0
+# PLT-NEXT:    Size: 48
+# PLT-NEXT:    Link: 0
+# PLT-NEXT:    Info: 0
+# PLT-NEXT:    AddressAlignment: 16
+# PLT-NEXT:    EntrySize: 0
+# PLT-NEXT:  }
+
+# PLT:      Relocations [
+# PLT-NEXT:   Section (5) .rel.dyn {
+# PLT-NEXT:     0x400120 R_MIPS_REL32 T1 0x0
+# PLT-NEXT:   }
+# PLT-NEXT:   Section (6) .rel.plt {
+# PLT-NEXT:     0x403008 R_MIPS_JUMP_SLOT T2 0x0
+# PLT-NEXT:     0x40300C R_MIPS_JUMP_SLOT T3 0x0
+# PLT-NEXT:   }
+# PLT-NEXT: ]
+
+# PLT:      DynamicSymbols [
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: @ (0)
+# PLT-NEXT:     Value: 0x0
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Local (0x0)
+# PLT-NEXT:     Type: None (0x0)
+# PLT-NEXT:     Other: 0
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: T3@ (1)
+# PLT-NEXT:     Value: 0x4010E5
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Global (0x1)
+# PLT-NEXT:     Type: Function (0x2)
+# PLT-NEXT:     Other: 8
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: T2@ (7)
+# PLT-NEXT:     Value: 0x4010D9
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Global (0x1)
+# PLT-NEXT:     Type: Function (0x2)
+# PLT-NEXT:     Other: 8
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: T1@ (4)
+# PLT-NEXT:     Value: 0x0
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Global (0x1)
+# PLT-NEXT:     Type: Function (0x2)
+# PLT-NEXT:     Other: 0
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT: ]
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: T1
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 4
+    - Name: T2
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x4
+      Size: 4
+    - Name: T3
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x8
+      Size: 4
+
+# o.o
+---
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Size: 0x14
+  AddressAlign: 16
+  Flags: [SHF_WRITE, SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    # There is no branch relocation for T1.
+    - Offset: 0x00
+      Symbol: T1
+      Type: R_MIPS_32
+    # The R_MIPS_32 relocation for T2 might produce R_MIPS_REL32 ...
+    - Offset: 0x04
+      Symbol: T2
+      Type: R_MIPS_32
+    # ... but R_MICROMIPS_26_S1 creates PLT entry
+    # and makes R_MIPS_REL32 redundant.
+    - Offset: 0x08
+      Symbol: T2
+      Type: R_MICROMIPS_26_S1
+    # Create PLT entry for T3 symbol.
+    - Offset: 0x0c
+      Symbol: T3
+      Type: R_MICROMIPS_26_S1
+    # Take in account existing PLT entry and do not create R_MIPS_REL32.
+    - Offset: 0x10
+      Symbol: T3
+      Type: R_MIPS_32
+
+Symbols:
+  Global:
+    - Name: T0
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 0x14
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: T2
+      Type: STT_FUNC
+    - Name: T3
+      Type: STT_FUNC
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-05-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-05-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-05-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-05-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,192 @@
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) Relocations' targets are symbols defined in the shared object.
+#   c) Relocations modify a read-only section.
+#   d) The first symbol is referenced by R_MIPS32 relocation only
+#   e) The second symbol is referenced by R_MIPS_32
+#      and R_MICROMIPS_26_S1 relocations.
+#   f) The third symbol is referenced by R_MICROMIPS_26_S1
+#      and R_MIPS_32 relocations.
+# Check:
+#   a) There should be no R_MIPS_REL32 relocations.
+#   b) Linker creates PLT entries for all three relocations.
+#   c) STO_MIPS_PLT flag in the dynamic symbol table for symbols require
+#      a pointer equality.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
+# RUN: llvm-readobj -dt -r -s %t.exe | FileCheck -check-prefix=PLT %s
+
+# PLT:      Section {
+# PLT:        Index: 5
+# PLT-NEXT:    Name: .rel.plt (31)
+# PLT-NEXT:    Type: SHT_REL (0x9)
+# PLT-NEXT:    Flags [ (0x2)
+# PLT-NEXT:      SHF_ALLOC (0x2)
+# PLT-NEXT:    ]
+# PLT-NEXT:    Address: 0x400194
+# PLT-NEXT:    Offset: 0x194
+# PLT-NEXT:    Size: 24
+# PLT-NEXT:    Link: 3
+# PLT-NEXT:    Info: 0
+# PLT-NEXT:    AddressAlignment: 4
+# PLT-NEXT:    EntrySize: 8
+# PLT-NEXT:  }
+# PLT-NEXT:  Section {
+# PLT-NEXT:    Index: 6
+# PLT-NEXT:    Name: .plt (40)
+# PLT-NEXT:    Type: SHT_PROGBITS (0x1)
+# PLT-NEXT:    Flags [ (0x6)
+# PLT-NEXT:      SHF_ALLOC (0x2)
+# PLT-NEXT:      SHF_EXECINSTR (0x4)
+# PLT-NEXT:    ]
+# PLT-NEXT:    Address: 0x4001B0
+# PLT-NEXT:    Offset: 0x1B0
+# PLT-NEXT:    Size: 60
+# PLT-NEXT:    Link: 0
+# PLT-NEXT:    Info: 0
+# PLT-NEXT:    AddressAlignment: 16
+# PLT-NEXT:    EntrySize: 0
+# PLT-NEXT:  }
+
+# PLT:      Relocations [
+# PLT-NEXT:   Section (5) .rel.plt {
+# PLT-NEXT:     0x402008 R_MIPS_JUMP_SLOT T1 0x0
+# PLT-NEXT:     0x40200C R_MIPS_JUMP_SLOT T2 0x0
+# PLT-NEXT:     0x402010 R_MIPS_JUMP_SLOT T3 0x0
+# PLT-NEXT:   }
+# PLT-NEXT: ]
+
+# PLT:      DynamicSymbols [
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: @ (0)
+# PLT-NEXT:     Value: 0x0
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Local (0x0)
+# PLT-NEXT:     Type: None (0x0)
+# PLT-NEXT:     Other: 0
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: T3@ (1)
+# PLT-NEXT:     Value: 0x4001E1
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Global (0x1)
+# PLT-NEXT:     Type: Function (0x2)
+# PLT-NEXT:     Other: 8
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: T1@ (4)
+# PLT-NEXT:     Value: 0x4001C9
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Global (0x1)
+# PLT-NEXT:     Type: Function (0x2)
+# PLT-NEXT:     Other: 8
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT:   Symbol {
+# PLT-NEXT:     Name: T2@ (7)
+# PLT-NEXT:     Value: 0x4001D5
+# PLT-NEXT:     Size: 0
+# PLT-NEXT:     Binding: Global (0x1)
+# PLT-NEXT:     Type: Function (0x2)
+# PLT-NEXT:     Other: 8
+# PLT-NEXT:     Section: Undefined (0x0)
+# PLT-NEXT:   }
+# PLT-NEXT: ]
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: T1
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 4
+    - Name: T2
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x4
+      Size: 4
+    - Name: T3
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x8
+      Size: 4
+
+# o.o
+---
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Size: 0x14
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    # There is no branch relocation for T1.
+    - Offset: 0x00
+      Symbol: T1
+      Type: R_MIPS_32
+    # The R_MIPS_32 relocation for T2 might produce R_MIPS_REL32 ...
+    - Offset: 0x04
+      Symbol: T2
+      Type: R_MIPS_32
+    # ... but R_MICROMIPS_26_S1 creates PLT entry and makes R_MIPS_REL32 redundant.
+    - Offset: 0x08
+      Symbol: T2
+      Type: R_MICROMIPS_26_S1
+    # Create PLT entry for T3 symbol.
+    - Offset: 0x0C
+      Symbol: T3
+      Type: R_MICROMIPS_26_S1
+    # Take in account existing PLT entry and do not create R_MIPS_REL32.
+    - Offset: 0x10
+      Symbol: T3
+      Type: R_MIPS_32
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    0x14
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: T2
+      Type: STT_FUNC
+    - Name: T3
+      Type: STT_FUNC
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-08-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-08-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-08-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-08-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,236 @@
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) There ars multiple R_MIPS_32/R_MICROMIPS_HI16/R_MICROMIPS_LO16
+#      relocations with various targets.
+# Check:
+#   a) Emitting of R_MIPS_REL32 relocations.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e T0 --noinhibit-exec \
+# RUN:     -o %t.exe %t-o.o %t.so
+# RUN: llvm-readobj -dt -r -sections %t.exe | FileCheck %s
+
+# CHECK:   Sections [
+# CHECK:     Section {
+# CHECK-NOT:   Name: .plt ({{[0-9]+}})
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section (5) .rel.dyn {
+# CHECK-NEXT:     0x402000 R_MIPS_REL32 D2 0x0
+# CHECK-NEXT:     0x402004 R_MIPS_REL32 T1 0x0
+# CHECK-NEXT:     0x402008 R_MIPS_REL32 T2 0x0
+# CHECK-NEXT:     0x402008 R_MIPS_REL32 D1 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# CHECK:      DynamicSymbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: @ (0)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local (0x0)
+# CHECK-NEXT:     Type: None (0x0)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: D2@ (10)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 4
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Object (0x1)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: T1@ (1)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Function (0x2)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: T2@ (4)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Function (0x2)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: D1@ (7)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 4
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Object (0x1)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name: T1
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x0
+      Size: 4
+    - Name: T2
+      Section: .text
+      Type: STT_FUNC
+      Value: 0x4
+      Size: 4
+    - Name: D1
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 4
+    - Name: D2
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x4
+      Size: 4
+
+# o.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Size: 0x0C
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .data
+  Type: SHT_PROGBITS
+  Size: 0x0C
+  AddressAlign: 16
+  Flags: [SHF_WRITE, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: _gp_disp
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: _gp_disp
+      Type: R_MICROMIPS_LO16
+
+- Name: .rel.data
+  Type: SHT_REL
+  Info: .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00      # LT0 is a locally defined function
+      Symbol: LT0
+      Type: R_MIPS_32
+    - Offset: 0x00      # LD0 is a locally defined data object
+      Symbol: LD0
+      Type: R_MIPS_32
+    - Offset: 0x00      # T0 is a defined function
+      Symbol: T0
+      Type: R_MIPS_32
+    - Offset: 0x04      # T1 is a function from shared lib
+      Symbol: T1
+      Type: R_MIPS_32
+    - Offset: 0x08      # T2 has unknown type and defined in shared lib
+      Symbol: T2
+      Type: R_MIPS_32
+    - Offset: 0x00      # T4 is an undefined function
+      Symbol: T4
+      Type: R_MIPS_32
+    - Offset: 0x04      # D0 is a defined data object
+      Symbol: D0
+      Type: R_MIPS_32
+    - Offset: 0x08      # D1 is a data object from shared lib
+      Symbol: D1
+      Type: R_MIPS_32
+    - Offset: 0x00      # D2 has unknown type and defined in shared lib
+      Symbol: D2
+      Type: R_MIPS_32
+    - Offset: 0x04      # D4 is an undefined data object
+      Symbol: D4
+      Type: R_MIPS_32
+    - Offset: 0x08      # U1 is undefined and has unknown type
+      Symbol: U1
+      Type: R_MIPS_32
+
+Symbols:
+  Local:
+    - Name:    LT0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    LD0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x0
+      Size:    4
+
+  Global:
+    - Name: _gp_disp
+      Type: STT_OBJECT
+
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x4
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: T2
+    - Name: T4
+      Type: STT_FUNC
+
+    - Name:    D0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x4
+      Size:    8
+    - Name: D1
+      Type: STT_OBJECT
+    - Name: D2
+    - Name: D4
+      Type: STT_OBJECT
+    - Name: U1
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-09-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-09-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-09-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-09-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,109 @@
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) Relocations' targets are undefined symbols.
+# Check:
+#   a) There should be no dynamic relocations.
+#   b) There should be no PLT entries.
+#
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel --noinhibit-exec -e T0 -o %t2-exe %t-obj
+# RUN: llvm-readobj -dt -r -s %t2-exe | FileCheck -check-prefix=PLT-SYM %s
+
+# PLT-SYM:     Sections [
+# PLT-SYM:       Section {
+# PLT-SYM-NOT:     Name: .plt ({{[0-9]+}})
+
+# PLT-SYM:      Relocations [
+# PLT-SYM-NEXT: ]
+
+# PLT-SYM:      DynamicSymbols [
+# PLT-SYM-NEXT:   Symbol {
+# PLT-SYM-NEXT:     Name: @ (0)
+# PLT-SYM-NEXT:     Value: 0x0
+# PLT-SYM-NEXT:     Size: 0
+# PLT-SYM-NEXT:     Binding: Local (0x0)
+# PLT-SYM-NEXT:     Type: None (0x0)
+# PLT-SYM-NEXT:     Other: 0
+# PLT-SYM-NEXT:     Section: Undefined (0x0)
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT: ]
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Content:  "0000000000000000"
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .data
+  Type: SHT_PROGBITS
+  Content:  "0000000000000000"
+  AddressAlign: 16
+  Flags: [SHF_WRITE, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x04
+      Symbol: T3
+      Type: R_MICROMIPS_26_S1
+
+- Name: .rel.data
+  Type: SHT_REL
+  Info: .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: T1
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: T1
+      Type: R_MICROMIPS_LO16
+    - Offset: 0x04
+      Symbol: T2
+      Type: R_MIPS_32
+
+    - Offset: 0x04
+      Symbol: D1
+      Type: R_MICROMIPS_HI16
+    - Offset: 0x04
+      Symbol: D1
+      Type: R_MICROMIPS_LO16
+    - Offset: 0x04
+      Symbol: D2
+      Type: R_MIPS_32
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: T2
+      Type: STT_FUNC
+    - Name: T3
+      Type: STT_FUNC
+    - Name:    D0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x0
+      Size:    8
+    - Name: D1
+      Type: STT_OBJECT
+    - Name: D2
+      Type: STT_OBJECT

Added: lld/trunk/test/elf/Mips/rel-dynamic-10-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-10-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-10-micro.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-10-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,166 @@
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) Relocations' targets are symbols defined in the other object.
+# Check:
+#   a) There should be no dynamic relocations.
+#   b) There should be no PLT entries.
+#
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-o1.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o2.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o1.o %t-o2.o
+# RUN: llvm-readobj -dt -r -s %t.exe | FileCheck -check-prefix=PLT-SYM %s
+
+# PLT-SYM:     Sections [
+# PLT-SYM:       Section {
+# PLT-SYM-NOT:     Name: .plt ({{[0-9]+}})
+
+# PLT-SYM:      Relocations [
+# PLT-SYM-NEXT: ]
+
+# PLT-SYM:      DynamicSymbols [
+# PLT-SYM-NEXT:   Symbol {
+# PLT-SYM-NEXT:     Name: @ (0)
+# PLT-SYM-NEXT:     Value: 0x0
+# PLT-SYM-NEXT:     Size: 0
+# PLT-SYM-NEXT:     Binding: Local (0x0)
+# PLT-SYM-NEXT:     Type: None (0x0)
+# PLT-SYM-NEXT:     Other: 0
+# PLT-SYM-NEXT:     Section: Undefined (0x0)
+# PLT-SYM-NEXT:   }
+# PLT-SYM-NEXT: ]
+
+# o1.o
+---
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x0C
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_WRITE, SHF_ALLOC]
+
+Symbols:
+  Global:
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    T2
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x4
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    T3
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x8
+      Size:    4
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    D1
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x0
+      Size:    4
+    - Name:    D2
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0x4
+      Size:    4
+
+# o2.o
+---
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name: .text
+  Type: SHT_PROGBITS
+  Size: 0x08
+  AddressAlign: 16
+  Flags: [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name: .data
+  Type: SHT_PROGBITS
+  Size: 0x08
+  AddressAlign: 16
+  Flags: [SHF_WRITE, SHF_ALLOC]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x04
+      Symbol: T3
+      Type:   R_MICROMIPS_26_S1
+
+- Name: .rel.data
+  Type: SHT_REL
+  Info: .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: T1
+      Type:   R_MICROMIPS_HI16
+    - Offset: 0x00
+      Symbol: T1
+      Type:   R_MICROMIPS_LO16
+    - Offset: 0x04
+      Symbol: T2
+      Type:   R_MIPS_32
+
+    - Offset: 0x04
+      Symbol: D1
+      Type:   R_MICROMIPS_HI16
+    - Offset: 0x04
+      Symbol: D1
+      Type:   R_MICROMIPS_LO16
+    - Offset: 0x04
+      Symbol: D2
+      Type:   R_MIPS_32
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    8
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name: T1
+      Type: STT_FUNC
+    - Name: T2
+      Type: STT_FUNC
+    - Name: T3
+      Type: STT_FUNC
+    - Name: D0
+      Section: .data
+      Type: STT_OBJECT
+      Value: 0x0
+      Size: 8
+    - Name: D1
+      Type: STT_OBJECT
+    - Name: D2
+      Type: STT_OBJECT
+...

Added: lld/trunk/test/elf/Mips/rel-pc7-10-16-23.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-pc7-10-16-23.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-pc7-10-16-23.test (added)
+++ lld/trunk/test/elf/Mips/rel-pc7-10-16-23.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,86 @@
+# Check handling of R_MICROMIPS_PC7_S1, R_MICROMIPS_PC10_S1,
+# R_MICROMIPS_PC16_S1, and R_MICROMIPS_PC23_S2 relocations.
+
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel -o %t-exe %t-obj
+# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK-NEXT: 400110 00000000 80780500 a240fcff 000c03cc  .....x... at ......
+#                             ^^ addiu  s1,$pc,20
+#                                      ^^ bnezc  v0,400114 <__start+0x4>
+#                                                   ^^ b  400126 <L1>
+# CHECK-NEXT: 400120 000c03ad 00000000 00000000 00000000  ................
+#                        ^^ bnez  v0,40012a <L2>
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400124 l  F .text  00000002 L0
+# CHECK: 00400126 l  F .text  00000004 L1
+# CHECK: 0040012a l  F .text  00000004 L2
+# CHECK: 0040012e l  F .text  00000002 L3
+# CHECK: 00400110 g  F .text  00000014 __start
+
+!ELF
+FileHeader: !FileHeader
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [ EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
+             EF_MIPS_MICROMIPS ]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+#                                        v nop   v nop   v L0
+  Content:      "0000000080780100a240f5ff000cfdcf000c7dad000000000000000000000000"
+#                        ^ PC23  ^ PC16      ^ PC10  ^ PC7   ^ L1    ^ L2    ^ L3
+#                                                    7d << 1 = -6 => L3 + 2 - 6 = L2
+#                                            3fd << 1 = -6 => L2 + 2 - 6 = L1
+#                                fff5 << 1 = -22 => L1 + 2 - 22 = __start
+#                        1 << 2 = 4 => L0 + 4 - 4 = L0
+  AddressAlign: 16
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+
+- Name: .rel.text
+  Type: SHT_REL
+  Info: .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 4
+      Symbol: L0
+      Type:   R_MICROMIPS_PC23_S2
+    - Offset: 8
+      Symbol: L1
+      Type:   R_MICROMIPS_PC16_S1
+    - Offset: 14
+      Symbol: L2
+      Type:   R_MICROMIPS_PC10_S1
+    - Offset: 18
+      Symbol: L3
+      Type:   R_MICROMIPS_PC7_S1
+
+Symbols:
+  Local:
+    - Name:    L0
+      Section: .text
+      Value:   20
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    L1
+      Section: .text
+      Value:   22
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    L2
+      Section: .text
+      Value:   26
+      Other:   [ STO_MIPS_MICROMIPS ]
+    - Name:    L3
+      Section: .text
+      Value:   30
+      Other:   [ STO_MIPS_MICROMIPS ]
+  Global:
+    - Name:    __start
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    32
+      Other:   [ STO_MIPS_MICROMIPS ]

Added: lld/trunk/test/elf/Mips/tls-1-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-1-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-1-micro.test (added)
+++ lld/trunk/test/elf/Mips/tls-1-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,65 @@
+# Check handling of R_MICROMIPS_TLS_TPREL_HI16 / R_MICROMIPS_TLS_TPREL_LO16
+# relocations.
+
+# RUN: yaml2obj -format=elf -o %t.o %s
+# RUN: lld -flavor gnu -target mipsel -e L0 -o %t.exe %t.o
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK:  400150 00000000 00000100 00000380 00000480  ................
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x10
+    Content:         '00000100000002000000030000000400'
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          L1
+        Type:            R_MICROMIPS_TLS_TPREL_HI16
+      - Offset:          0x04
+        Symbol:          L2
+        Type:            R_MICROMIPS_TLS_TPREL_HI16
+      - Offset:          0x08
+        Symbol:          L2
+        Type:            R_MICROMIPS_TLS_TPREL_LO16
+      - Offset:          0x0C
+        Symbol:          L1
+        Type:            R_MICROMIPS_TLS_TPREL_LO16
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Address:         0x1000
+    Size:            0x20000
+
+Symbols:
+  Global:
+    - Name:            L0
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x58
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            L1
+      Type:            STT_TLS
+      Section:         .tdata
+      Value:           0x00
+      Size:            0x04
+    - Name:            L2
+      Type:            STT_TLS
+      Section:         .tdata
+      Value:           0x10000
+      Size:            0x04

Added: lld/trunk/test/elf/Mips/tls-2-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-2-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-2-micro.test (added)
+++ lld/trunk/test/elf/Mips/tls-2-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,70 @@
+# Check handling of R_MICROMIPS_TLS_GOTTPREL and R_MICROMIPS_TLS_GD relocations
+# and generation of corresponding dynamic relocations R_MIPS_TLS_TPREL32,
+# R_MIPS_TLS_DTPMOD32 and R_MIPS_TLS_DTPREL32 in case of shared library.
+
+# Create a shared library with thread symbol D1.
+# RUN: yaml2obj -format=elf -o %t-so.o %s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+
+# Check dynamic relocations and GOT in the shared library.
+# RUN: llvm-readobj -r %t.so | FileCheck -check-prefix=REL %s
+# RUN: llvm-readobj -dynamic-table %t.so | FileCheck -check-prefix=DYN %s
+# RUN: llvm-readobj -dt %t.so | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=GOT %s
+
+# REL:      Section (4) .rel.dyn {
+# REL-NEXT:   0x2008 R_MIPS_TLS_DTPMOD32 D1 0x0
+# REL-NEXT:   0x200C R_MIPS_TLS_DTPREL32 D1 0x0
+# REL-NEXT: }
+
+# DYN: 0x7000000A MIPS_LOCAL_GOTNO 2
+# DYN: 0x70000013 MIPS_GOTSYM      0x3
+
+# SYM: Name: T1@ (1)
+# SYM: Name: D1@ (4)
+
+# GOT:      Contents of section .got:
+# GOT-NEXT:  2000 00000000 00000080 00000000 00000000  ................
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x04
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          D1
+        Type:            R_MICROMIPS_TLS_GD
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Global:
+    - Name:            T1
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x04
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            D1
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+...

Added: lld/trunk/test/elf/Mips/tls-3-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-3-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-3-micro.test (added)
+++ lld/trunk/test/elf/Mips/tls-3-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,183 @@
+# Check handling of R_MICROMIPS_TLS_GOTTPREL and R_MICROMIPS_TLS_GD relocations
+# and generation of corresponding dynamic relocations R_MIPS_TLS_TPREL32,
+# R_MIPS_TLS_DTPMOD32 and R_MIPS_TLS_DTPREL32 in case of executable linking.
+
+# Create a shared library with thread symbol D1.
+# RUN: yaml2obj -format=elf -docnum 1 -o %t-so.o %s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
+
+# Create executable file linked using two object files and the shared library.
+# The object files defines thread symbols D0 and D2.
+# RUN: yaml2obj -format=elf -docnum 2 -o %t-o1.o %s
+# RUN: yaml2obj -format=elf -docnum 3 -o %t-o2.o %s
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o1.o %t-o2.o %t.so
+
+# Check dynamic relocations and GOT in the executable file.
+# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s
+# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=DYN %s
+# RUN: llvm-readobj -dt %t.exe | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=GOT %s
+
+# REL:      Section (5) .rel.dyn {
+# REL-NEXT:   0x402008 R_MIPS_TLS_TPREL32 D1 0x0
+# REL-NEXT:   0x40200C R_MIPS_TLS_TPREL32 D2 0x0
+# REL-NEXT: }
+
+# DYN: 0x7000000A MIPS_LOCAL_GOTNO 2
+# DYN: 0x70000013 MIPS_GOTSYM      0x3
+
+# SYM: Name: D2@ (1)
+# SYM: Name: D1@ (4)
+
+# GOT:      Contents of section .got:
+# GOT-NEXT:  402000 00000000 00000080 00000000 00000000  ................
+
+# so.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x04
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          D1
+        Type:            R_MICROMIPS_TLS_GD
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Global:
+    - Name:            T1
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x04
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            D1
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+
+# o1.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x08
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          D2
+        Type:            R_MICROMIPS_TLS_TPREL_HI16
+      - Offset:          0x04
+        Symbol:          D2
+        Type:            R_MICROMIPS_TLS_TPREL_LO16
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Global:
+    - Name:            T2
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x08
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            D2
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+
+# o2.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x10
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          D1
+        Type:            R_MICROMIPS_TLS_GOTTPREL
+        Addend:          0
+      - Offset:          0x04
+        Symbol:          D0
+        Type:            R_MICROMIPS_TLS_TPREL_HI16
+        Addend:          0
+      - Offset:          0x08
+        Symbol:          D0
+        Type:            R_MICROMIPS_TLS_TPREL_LO16
+        Addend:          0
+      - Offset:          0x0C
+        Symbol:          D2
+        Type:            R_MICROMIPS_TLS_GOTTPREL
+        Addend:          0
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Global:
+    - Name:            D0
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+    - Name:            T0
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x10
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            D1
+      Type:            STT_TLS
+    - Name:            D2
+      Type:            STT_TLS
+...

Added: lld/trunk/test/elf/Mips/tls-4-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-4-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-4-micro.test (added)
+++ lld/trunk/test/elf/Mips/tls-4-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,126 @@
+# Check handling of R_MICROMIPS_TLS_LDM relocation and generation
+# of corresponding dynamic relocation R_MICROMIPS_TLS_DTPMOD32.
+
+# RUN: yaml2obj -format=elf -docnum 1 -o %t-so1.o %s
+# RUN: yaml2obj -format=elf -docnum 2 -o %t-so2.o %s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so1.o %t-so2.o
+
+# RUN: llvm-readobj -r %t.so | FileCheck -check-prefix=REL %s
+# RUN: llvm-readobj -dynamic-table %t.so | FileCheck -check-prefix=DYN %s
+# RUN: llvm-readobj -dt %t.so | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=GOT %s
+
+# REL:      Section (4) .rel.dyn {
+# REL-NEXT:   0x2008 R_MIPS_TLS_DTPMOD32 - 0x0
+# REL-NEXT: }
+
+# DYN: 0x7000000A MIPS_LOCAL_GOTNO 2
+# DYN: 0x70000013 MIPS_GOTSYM      0x4
+
+# SYM: Name: @ (0)
+# SYM: Name: T1@ (1)
+# SYM: Name: T2@ (4)
+# SYM: Name: T3@ (7)
+
+# GOT:      Contents of section .got:
+# GOT-NEXT:  2000 00000000 00000080 00000000 00000000  ................
+#                 Two LDM entries --^--------^
+
+# so1.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x08
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          L01
+        Type:            R_MICROMIPS_TLS_LDM
+      - Offset:          0x04
+        Symbol:          L01
+        Type:            R_MICROMIPS_TLS_LDM
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Local:
+    - Name:            L01
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+  Global:
+    - Name:            T1
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x00
+      Size:            0x04
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            T2
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x04
+      Size:            0x04
+      Other:           [ STO_MIPS_MICROMIPS ]
+
+# so2.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x04
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          L02
+        Type:            R_MICROMIPS_TLS_LDM
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Local:
+    - Name:            L02
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+  Global:
+    - Name:            T3
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x04
+      Other:           [ STO_MIPS_MICROMIPS ]
+...

Added: lld/trunk/test/elf/Mips/tls-5-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-5-micro.test?rev=224826&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-5-micro.test (added)
+++ lld/trunk/test/elf/Mips/tls-5-micro.test Wed Dec 24 15:04:05 2014
@@ -0,0 +1,70 @@
+# Check that in case of an executable file linking symbol referred by
+# the R_MICROMIPS_TLS_GD relocation gets an entry in the dynamic symbol table.
+
+# RUN: yaml2obj -format=elf -o %t-o.o %s
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o
+
+# Check dynamic relocations:
+# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s
+# Check dynamic symbol table:
+# RUN: llvm-readobj -dt %t.exe | FileCheck -check-prefix=SYM %s
+
+# REL:      Relocations [
+# REL-NEXT:   Section (5) .rel.dyn {
+# REL-NEXT:     0x402008 R_MIPS_TLS_DTPMOD32 T1 0x0
+# REL-NEXT:     0x40200C R_MIPS_TLS_DTPREL32 T1 0x0
+# REL-NEXT:   }
+# REL-NEXT: ]
+
+# SYM:      Symbol {
+# SYM:        Name: T1@ (1)
+# SYM-NEXT:   Value: 0x0
+# SYM-NEXT:   Size: 4
+# SYM-NEXT:   Binding: Global (0x1)
+# SYM-NEXT:   Type: TLS (0x6)
+# SYM-NEXT:   Other: 0
+# SYM-NEXT:   Section: .tdata (0x7)
+# SYM-NEXT: }
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x10
+    Size:            0x04
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x04
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          T1
+        Type:            R_MICROMIPS_TLS_GD
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Global:
+    - Name:            T0
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x04
+      Other:           [ STO_MIPS_MICROMIPS ]
+    - Name:            T1
+      Type:            STT_TLS
+      Section:         .tdata
+      Value:           0x00
+      Size:            0x04
+...





More information about the llvm-commits mailing list