[lld] r210394 - [Mips] Handle Mips TLS relocations R_MIPS_TLS_GOTTPREL / R_MIPS_TLS_GD / R_MIPS_TLS_LDM etc.

Simon Atanasyan simon at atanasyan.com
Sat Jun 7 06:20:56 PDT 2014


Author: atanasyan
Date: Sat Jun  7 08:20:53 2014
New Revision: 210394

URL: http://llvm.org/viewvc/llvm-project?rev=210394&view=rev
Log:
[Mips] Handle Mips TLS relocations R_MIPS_TLS_GOTTPREL / R_MIPS_TLS_GD / R_MIPS_TLS_LDM etc.

Added:
    lld/trunk/test/elf/Mips/tls-2.test
    lld/trunk/test/elf/Mips/tls-3.test
    lld/trunk/test/elf/Mips/tls-4.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp

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=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Sat Jun  7 08:20:53 2014
@@ -118,6 +118,7 @@ public:
 
   /// \brief .tdata section address plus fixed offset.
   uint64_t getTPOffset() const { return *_tpOff; }
+  uint64_t getDTPOffset() const { return *_dtpOff; }
 
 private:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
@@ -125,10 +126,11 @@ private:
   typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel_Iter Elf_Rel_Iter;
 
-  enum { TP_OFFSET = 0x7000 };
+  enum { TP_OFFSET = 0x7000, DTP_OFFSET = 0x8000 };
 
   llvm::Optional<int64_t> _gp0;
   llvm::Optional<uint64_t> _tpOff;
+  llvm::Optional<uint64_t> _dtpOff;
 
   ErrorOr<ELFDefinedAtom<ELFT> *> handleDefinedSymbol(
       StringRef symName, StringRef sectionName, const Elf_Sym *sym,
@@ -155,8 +157,10 @@ private:
         assert(raw.size() == sizeof(Elf_RegInfo) &&
                "Invalid size of RegInfo section");
         _gp0 = reinterpret_cast<const Elf_RegInfo *>(raw.data())->ri_gp_value;
-      } else if (!_tpOff.hasValue() && section.sh_flags & llvm::ELF::SHF_TLS)
+      } else if (!_tpOff.hasValue() && section.sh_flags & llvm::ELF::SHF_TLS) {
         _tpOff = section.sh_addr + TP_OFFSET;
+        _dtpOff = section.sh_addr + DTP_OFFSET;
+      }
     }
     return error_code();
   }
@@ -201,6 +205,11 @@ private:
     case llvm::ELF::R_MIPS_HI16:
     case llvm::ELF::R_MIPS_LO16:
     case llvm::ELF::R_MIPS_GOT16:
+    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_MIPS_TLS_DTPREL_HI16:
+    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 *(int16_t *)ap;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h Sat Jun  7 08:20:53 2014
@@ -59,6 +59,14 @@ template <class ELFT>
 void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
   // MIPS ABI requires to add to dynsym even undefined symbols
   // if they have a corresponding entries in a global part of GOT.
+  for (auto sec : this->_layout.sections())
+    if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
+      for (const auto &atom : section->atoms()) {
+        if (_writeHelper.hasGlobalGOTEntry(atom->_atom))
+          this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+                                               atom->_virtualAddr, atom);
+      }
+
   for (const UndefinedAtom *a : file.undefined())
     // FIXME (simon): Consider to move this check to the
     // MipsELFUndefinedAtom class method. That allows to

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=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Sat Jun  7 08:20:53 2014
@@ -56,6 +56,9 @@ bool MipsLinkingContext::isDynamicReloca
   switch (r.kindValue()) {
   case llvm::ELF::R_MIPS_COPY:
   case llvm::ELF::R_MIPS_REL32:
+  case llvm::ELF::R_MIPS_TLS_DTPMOD32:
+  case llvm::ELF::R_MIPS_TLS_DTPREL32:
+  case llvm::ELF::R_MIPS_TLS_TPREL32:
     return true;
   default:
     return false;

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=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Sat Jun  7 08:20:53 2014
@@ -92,14 +92,14 @@ static void relocGOT(uint8_t *location,
   applyReloc(location, G, 0xffff);
 }
 
-/// \brief R_MIPS_TLS_TPREL_HI16, LLD_R_MIPS_HI16
+/// \brief R_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_TPREL_HI16, LLD_R_MIPS_HI16
 /// (S + A) >> 16
 static void relocGeneralHi16(uint8_t *location, uint64_t S, int64_t A) {
   int32_t result = S + A + 0x8000;
   applyReloc(location, result >> 16, 0xffff);
 }
 
-/// \brief R_MIPS_TLS_TPREL_LO16, LLD_R_MIPS_LO16
+/// \brief R_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_TPREL_LO16, LLD_R_MIPS_LO16
 /// S + A
 static void relocGeneralLo16(uint8_t *location, uint64_t S, int64_t A) {
   int32_t result = S + A;
@@ -158,9 +158,18 @@ error_code MipsTargetRelocationHandler::
   case R_MIPS_CALL16:
     relocGOT(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
     break;
+  case R_MIPS_TLS_GD:
+    relocGOT(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
+    break;
+  case R_MIPS_TLS_LDM:
+  case R_MIPS_TLS_GOTTPREL:
+    relocGOT(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
+    break;
+  case R_MIPS_TLS_DTPREL_HI16:
   case R_MIPS_TLS_TPREL_HI16:
     relocGeneralHi16(location, targetVAddress, ref.addend());
     break;
+  case R_MIPS_TLS_DTPREL_LO16:
   case R_MIPS_TLS_TPREL_LO16:
     relocGeneralLo16(location, targetVAddress, ref.addend());
     break;
@@ -173,6 +182,9 @@ error_code MipsTargetRelocationHandler::
   case R_MIPS_REL32:
   case R_MIPS_JUMP_SLOT:
   case R_MIPS_COPY:
+  case R_MIPS_TLS_DTPMOD32:
+  case R_MIPS_TLS_DTPREL32:
+  case R_MIPS_TLS_TPREL32:
     // Ignore runtime relocations.
     break;
   case R_MIPS_PC32:

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=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Sat Jun  7 08:20:53 2014
@@ -28,6 +28,12 @@ static const uint8_t mipsGotModulePointe
   0x00, 0x00, 0x00, 0x80
 };
 
+// TLS GD Entry
+static const uint8_t mipsGotTlsGdAtomContent[] = {
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
 // PLT0 entry
 static const uint8_t mipsPlt0AtomContent[] = {
   0x00, 0x00, 0x1c, 0x3c, // lui   $28, %hi(&GOTPLT[0])
@@ -86,6 +92,16 @@ public:
   }
 };
 
+/// \brief MIPS GOT TLS GD entry.
+class GOTTLSGdAtom : public MipsGOTAtom {
+public:
+  GOTTLSGdAtom(const File &f) : MipsGOTAtom(f) {}
+
+  ArrayRef<uint8_t> rawContent() const override {
+    return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
+  }
+};
+
 class PLT0Atom : public PLTAtom {
 public:
   PLT0Atom(const File &f) : PLTAtom(f, ".plt") {}
@@ -156,12 +172,24 @@ private:
   /// \brief Map Atoms to global GOT entries.
   llvm::DenseMap<const Atom *, GOTAtom *> _gotGlobalMap;
 
+  /// \brief Map Atoms to TLS GOT entries.
+  llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSMap;
+
+  /// \brief Map Atoms to TLS GD GOT entries.
+  llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSGdMap;
+
+  /// \brief GOT entry for the R_MIPS_TLS_LDM relocation.
+  GOTTLSGdAtom *_gotLDMEntry;
+
   /// \brief the list of local GOT atoms.
   std::vector<GOTAtom *> _localGotVector;
 
   /// \brief the list of global GOT atoms.
   std::vector<GOTAtom *> _globalGotVector;
 
+  /// \brief the list of TLS GOT atoms.
+  std::vector<GOTAtom *> _tlsGotVector;
+
   /// \brief Map Atoms to their PLT entries.
   llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
 
@@ -205,10 +233,12 @@ private:
   void handle26(Reference &ref);
   void handleGOT(Reference &ref);
   void handleGPRel(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
-  void handleTLS(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
 
   const GOTAtom *getLocalGOTEntry(const Reference &ref);
   const GOTAtom *getGlobalGOTEntry(const Atom *a);
+  const GOTAtom *getTLSGOTEntry(const Atom *a);
+  const GOTAtom *getTLSGdGOTEntry(const Atom *a);
+  const GOTAtom *getTLSLdmGOTEntry(const Atom *a);
   PLTAtom *getPLTEntry(const Atom *a);
   const LA25Atom *getLA25Entry(const Atom *a);
   const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);
@@ -230,7 +260,7 @@ private:
 
 template <typename ELFT>
 RelocationPass<ELFT>::RelocationPass(MipsLinkingContext &context)
-    : _context(context), _file(context) {
+    : _context(context), _file(context), _gotLDMEntry(nullptr) {
   _localGotVector.push_back(new (_file._alloc) GOT0Atom(_file));
   _localGotVector.push_back(new (_file._alloc) GOTModulePointerAtom(_file));
 }
@@ -275,6 +305,11 @@ void RelocationPass<ELFT>::perform(std::
     mf->addAtom(*got);
   }
 
+  for (auto &got : _tlsGotVector) {
+    got->setOrdinal(ordinal++);
+    mf->addAtom(*got);
+  }
+
   for (auto &plt : _pltVector) {
     DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ PLT ] Adding " << plt->name()
                                             << "\n");
@@ -326,9 +361,22 @@ void RelocationPass<ELFT>::handleReferen
   case R_MIPS_GPREL32:
     handleGPRel(atom, ref);
     break;
+  case R_MIPS_TLS_DTPREL_HI16:
+  case R_MIPS_TLS_DTPREL_LO16:
+    ref.setAddend(ref.addend() - atom.file().getDTPOffset());
+    break;
   case R_MIPS_TLS_TPREL_HI16:
   case R_MIPS_TLS_TPREL_LO16:
-    handleTLS(atom, ref);
+    ref.setAddend(ref.addend() - atom.file().getTPOffset());
+    break;
+  case R_MIPS_TLS_GD:
+    ref.setTarget(getTLSGdGOTEntry(ref.target()));
+    break;
+  case R_MIPS_TLS_LDM:
+    ref.setTarget(getTLSLdmGOTEntry(ref.target()));
+    break;
+  case R_MIPS_TLS_GOTTPREL:
+    ref.setTarget(getTLSGOTEntry(ref.target()));
     break;
   }
 }
@@ -513,15 +561,6 @@ void RelocationPass<ELFT>::handleGPRel(c
 }
 
 template <typename ELFT>
-void RelocationPass<ELFT>::handleTLS(const MipsELFDefinedAtom<ELFT> &atom,
-                                     Reference &ref) {
-  assert((ref.kindValue() == R_MIPS_TLS_TPREL_HI16 ||
-          ref.kindValue() == R_MIPS_TLS_TPREL_LO16) &&
-         "Unexpected kind of relocation");
-  ref.setAddend(ref.addend() - atom.file().getTPOffset());
-}
-
-template <typename ELFT>
 bool RelocationPass<ELFT>::isLocalCall(const Atom *a) const {
   Atom::Scope scope;
   if (auto *da = dyn_cast<DefinedAtom>(a))
@@ -601,6 +640,49 @@ const GOTAtom *RelocationPass<ELFT>::get
   return ga;
 }
 
+template <typename ELFT>
+const GOTAtom *RelocationPass<ELFT>::getTLSGOTEntry(const Atom *a) {
+  auto got = _gotTLSMap.find(a);
+  if (got != _gotTLSMap.end())
+    return got->second;
+
+  auto ga = new (_file._alloc) GOT0Atom(_file);
+  _gotTLSMap[a] = ga;
+
+  _tlsGotVector.push_back(ga);
+  ga->addReferenceELF_Mips(R_MIPS_TLS_TPREL32, 0, a, 0);
+
+  return ga;
+}
+
+template <typename ELFT>
+const GOTAtom *RelocationPass<ELFT>::getTLSGdGOTEntry(const Atom *a) {
+  auto got = _gotTLSGdMap.find(a);
+  if (got != _gotTLSGdMap.end())
+    return got->second;
+
+  auto ga = new (_file._alloc) GOTTLSGdAtom(_file);
+  _gotTLSGdMap[a] = ga;
+
+  _tlsGotVector.push_back(ga);
+  ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, a, 0);
+  ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL32, 4, a, 0);
+
+  return ga;
+}
+
+template <typename ELFT>
+const GOTAtom *RelocationPass<ELFT>::getTLSLdmGOTEntry(const Atom *a) {
+  if (_gotLDMEntry)
+    return _gotLDMEntry;
+
+  _gotLDMEntry = new (_file._alloc) GOTTLSGdAtom(_file);
+  _tlsGotVector.push_back(_gotLDMEntry);
+  _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, _gotLDMEntry, 0);
+
+  return _gotLDMEntry;
+}
+
 template <typename ELFT> void RelocationPass<ELFT>::createPLTHeader() {
   assert(_pltVector.empty() && _gotpltVector.empty());
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h?rev=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Sat Jun  7 08:20:53 2014
@@ -21,21 +21,22 @@ public:
   MipsGOTSection(const MipsLinkingContext &context)
       : AtomSection<ELFType>(context, ".got", DefinedAtom::typeGOT,
                              DefinedAtom::permRW_,
-                             MipsTargetLayout<ELFType>::ORDER_GOT) {
+                             MipsTargetLayout<ELFType>::ORDER_GOT),
+        _hasNonLocal(false), _localCount(0) {
     this->_flags |= SHF_MIPS_GPREL;
     this->_align2 = 4;
   }
 
   /// \brief Number of local GOT entries.
-  std::size_t getLocalCount() const {
-    return this->_atoms.size() - getGlobalCount();
-  }
+  std::size_t getLocalCount() const { return _localCount; }
 
   /// \brief Number of global GOT entries.
   std::size_t getGlobalCount() const { return _posMap.size(); }
 
   /// \brief Does the atom have a global GOT entry?
-  bool hasGlobalGOTEntry(const Atom *a) const { return _posMap.count(a); }
+  bool hasGlobalGOTEntry(const Atom *a) const {
+    return _posMap.count(a) || _tlsMap.count(a);
+  }
 
   /// \brief Compare two atoms accordingly theirs positions in the GOT.
   bool compare(const Atom *a, const Atom *b) const {
@@ -51,24 +52,42 @@ public:
   const lld::AtomLayout &appendAtom(const Atom *atom) override {
     const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
 
-    const Atom *ta = nullptr;
     for (const auto &r : *da) {
       if (r->kindNamespace() != lld::Reference::KindNamespace::ELF)
         continue;
       assert(r->kindArch() == Reference::KindArch::Mips);
-      if (r->kindValue() == LLD_R_MIPS_GLOBAL_GOT) {
-        ta = r->target();
-        break;
+      switch (r->kindValue()) {
+      case LLD_R_MIPS_GLOBAL_GOT:
+        _hasNonLocal = true;
+        _posMap[r->target()] = _posMap.size();
+        return AtomSection<ELFType>::appendAtom(atom);
+      case R_MIPS_TLS_TPREL32:
+      case R_MIPS_TLS_DTPREL32:
+        _hasNonLocal = true;
+        _tlsMap[r->target()] = _tlsMap.size();
+        return AtomSection<ELFType>::appendAtom(atom);
+      case R_MIPS_TLS_DTPMOD32:
+        _hasNonLocal = true;
+        return AtomSection<ELFType>::appendAtom(atom);
       }
     }
 
-    if (ta)
-      _posMap[ta] = _posMap.size();
+    if (!_hasNonLocal)
+      ++_localCount;
 
     return AtomSection<ELFType>::appendAtom(atom);
   }
 
 private:
+  /// \brief True if the GOT contains non-local entries.
+  bool _hasNonLocal;
+
+  /// \brief Number of local GOT entries.
+  std::size_t _localCount;
+
+  /// \brief Map TLS Atoms to their GOT entry index.
+  llvm::DenseMap<const Atom *, std::size_t> _tlsMap;
+
   /// \brief Map Atoms to their GOT entry index.
   llvm::DenseMap<const Atom *, std::size_t> _posMap;
 };

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=210394&r1=210393&r2=210394&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Sat Jun  7 08:20:53 2014
@@ -57,6 +57,14 @@ const Registry::KindStrings MipsTargetHa
   LLD_KIND_STRING_ENTRY(R_MIPS_CALL16),
   LLD_KIND_STRING_ENTRY(R_MIPS_GPREL32),
   LLD_KIND_STRING_ENTRY(R_MIPS_JALR),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_DTPMOD32),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_DTPREL32),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_GD),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_LDM),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_GOTTPREL),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_TPREL32),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_DTPREL_HI16),
+  LLD_KIND_STRING_ENTRY(R_MIPS_TLS_DTPREL_LO16),
   LLD_KIND_STRING_ENTRY(R_MIPS_TLS_TPREL_HI16),
   LLD_KIND_STRING_ENTRY(R_MIPS_TLS_TPREL_LO16),
   LLD_KIND_STRING_ENTRY(R_MIPS_COPY),

Added: lld/trunk/test/elf/Mips/tls-2.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-2.test?rev=210394&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-2.test (added)
+++ lld/trunk/test/elf/Mips/tls-2.test Sat Jun  7 08:20:53 2014
@@ -0,0 +1,69 @@
+# Check handling of R_MIPS_TLS_GOTTPREL and R_MIPS_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 ]
+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_MIPS_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
+    - Name:            D1
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x04
+...

Added: lld/trunk/test/elf/Mips/tls-3.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-3.test?rev=210394&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-3.test (added)
+++ lld/trunk/test/elf/Mips/tls-3.test Sat Jun  7 08:20:53 2014
@@ -0,0 +1,180 @@
+# Check handling of R_MIPS_TLS_GOTTPREL and R_MIPS_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 ]
+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_MIPS_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
+    - 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 ]
+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_MIPS_TLS_TPREL_HI16
+      - Offset:          0x04
+        Symbol:          D2
+        Type:            R_MIPS_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
+    - 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 ]
+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_MIPS_TLS_GOTTPREL
+        Addend:          0
+      - Offset:          0x04
+        Symbol:          D0
+        Type:            R_MIPS_TLS_TPREL_HI16
+        Addend:          0
+      - Offset:          0x08
+        Symbol:          D0
+        Type:            R_MIPS_TLS_TPREL_LO16
+        Addend:          0
+      - Offset:          0x0C
+        Symbol:          D2
+        Type:            R_MIPS_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
+    - Name:            D1
+      Type:            STT_TLS
+    - Name:            D2
+      Type:            STT_TLS
+...

Added: lld/trunk/test/elf/Mips/tls-4.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-4.test?rev=210394&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-4.test (added)
+++ lld/trunk/test/elf/Mips/tls-4.test Sat Jun  7 08:20:53 2014
@@ -0,0 +1,123 @@
+# Check handling of R_MIPS_TLS_LDM relocation and generation of corresponding
+# dynamic relocation R_MIPS_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 ]
+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_MIPS_TLS_LDM
+      - Offset:          0x04
+        Symbol:          L01
+        Type:            R_MIPS_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
+    - Name:            T2
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x04
+      Size:            0x04
+
+# 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 ]
+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_MIPS_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
+...





More information about the llvm-commits mailing list