[lld] r233057 - [Mips] Support MIPS N64 relocation record format

Simon Atanasyan simon at atanasyan.com
Tue Mar 24 02:57:06 PDT 2015


Author: atanasyan
Date: Tue Mar 24 04:57:05 2015
New Revision: 233057

URL: http://llvm.org/viewvc/llvm-project?rev=233057&view=rev
Log:
[Mips] Support MIPS N64 relocation record format

N64 ABI relocation record r_info field in fact consists of five subfields:
* r_sym   - symbol index
* r_ssym  - special symbol
* r_type3 - third relocation type
* r_type2 - second relocation type
* r_type  - first relocation type

Up to three these relocations applied one by one. The first relocation
uses an addendum from the relocation record. Each subsequent relocation
takes as its addend the result of the previous operation. Only the final
operation actually modifies the location relocated. The first relocation
uses as a reference symbol specified by the `r_sym` field. The third
relocation assumes NULL symbol.

The patch represents these data using LLD model and takes in account
additional relocation types during a relocation calculation.

Additional relocations do not introduce any new relations between two
atoms and just specify operations need to be done during a relocation
calculation. The first relocation type (`r_type`) stored in the
`Reference::_kindValue`. The rest of relocations and `r_ssym` value are
stored in the new `Reference::_tag` field "as-is". I decided to do not
"decode" these data on the core LLD level to prevent pollution of the
core LLD model by very target specific data.

Also I have to override writing of relocation records in the `RelocationTable`
class to convert MIPS N64 ABI relocation information from the `Reference`
class back to the ELF relocation record.

http://reviews.llvm.org/D8533

Added:
    lld/trunk/test/elf/Mips/n64-rel-chain.test
    lld/trunk/test/elf/Mips/rel-dynamic-06-64.test
    lld/trunk/test/elf/Mips/rel-dynamic-07-64.test
    lld/trunk/test/elf/Mips/rel-dynamic-08-64.test
    lld/trunk/test/elf/Mips/rel-gprel32-64.test
Modified:
    lld/trunk/include/lld/Core/Reference.h
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
    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.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
    lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
    lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp

Modified: lld/trunk/include/lld/Core/Reference.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reference.h?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Reference.h (original)
+++ lld/trunk/include/lld/Core/Reference.h Tue Mar 24 04:57:05 2015
@@ -101,6 +101,9 @@ public:
   /// During linking, some optimzations may change addend value.
   virtual void setAddend(Addend) = 0;
 
+  /// Returns target specific attributes of the reference.
+  virtual uint32_t tag() const { return 0; }
+
 protected:
   /// Reference is an abstract base class.  Only subclasses can use constructor.
   Reference(KindNamespace ns, KindArch a, KindValue value)

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Tue Mar 24 04:57:05 2015
@@ -282,8 +282,8 @@ public:
   /// table are processed at startup.
   RelocationTable<ELFT> *getDynamicRelocationTable() {
     if (!_dynamicRelocationTable) {
-      _dynamicRelocationTable.reset(new (_allocator) RelocationTable<ELFT>(
-          _context, _context.isRelaOutputFormat() ? ".rela.dyn" : ".rel.dyn",
+      _dynamicRelocationTable = std::move(createRelocationTable(
+          _context.isRelaOutputFormat() ? ".rela.dyn" : ".rel.dyn",
           ORDER_DYNAMIC_RELOCS));
       addSection(_dynamicRelocationTable.get());
     }
@@ -293,8 +293,8 @@ public:
   /// \brief Get or create the PLT relocation table. Referenced by DT_JMPREL.
   RelocationTable<ELFT> *getPLTRelocationTable() {
     if (!_pltRelocationTable) {
-      _pltRelocationTable.reset(new (_allocator) RelocationTable<ELFT>(
-          _context, _context.isRelaOutputFormat() ? ".rela.plt" : ".rel.plt",
+      _pltRelocationTable = std::move(createRelocationTable(
+          _context.isRelaOutputFormat() ? ".rela.plt" : ".rel.plt",
           ORDER_DYNAMIC_PLT_RELOCS));
       addSection(_pltRelocationTable.get());
     }
@@ -331,6 +331,13 @@ protected:
       DefinedAtom::ContentPermissions contentPermissions,
       SectionOrder sectionOrder);
 
+  /// \brief Create a new relocation table.
+  virtual unique_bump_ptr<RelocationTable<ELFT>>
+  createRelocationTable(StringRef name, int32_t order) {
+    return unique_bump_ptr<RelocationTable<ELFT>>(
+        new (_allocator) RelocationTable<ELFT>(_context, name, order));
+  }
+
 private:
   /// Helper function that returns the priority value from an input section.
   uint32_t getPriorityFromSectionName(StringRef sectionName) const;

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=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Tue Mar 24 04:57:05 2015
@@ -89,6 +89,33 @@ public:
   }
 };
 
+template <class ELFT> class MipsELFReference : public ELFReference<ELFT> {
+  typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
+  typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
+
+  static const bool _isMips64EL =
+      ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+
+public:
+  MipsELFReference(uint64_t symValue, const Elf_Rela &rel)
+      : ELFReference<ELFT>(
+            &rel, rel.r_offset - symValue, Reference::KindArch::Mips,
+            rel.getType(_isMips64EL) & 0xff, rel.getSymbol(_isMips64EL)),
+        _tag(rel.getType(_isMips64EL) >> 8) {}
+
+  MipsELFReference(uint64_t symValue, const Elf_Rel &rel)
+      : ELFReference<ELFT>(rel.r_offset - symValue, Reference::KindArch::Mips,
+                           rel.getType(_isMips64EL) & 0xff,
+                           rel.getSymbol(_isMips64EL)),
+        _tag(rel.getType(_isMips64EL) >> 8) {}
+
+  uint32_t tag() const override { return _tag; }
+  void setTag(uint32_t tag) { _tag = tag; }
+
+private:
+  uint32_t _tag;
+};
+
 template <class ELFT> class MipsELFFile : public ELFFile<ELFT> {
 public:
   MipsELFFile(std::unique_ptr<MemoryBuffer> mb, MipsLinkingContext &ctx)
@@ -125,9 +152,13 @@ private:
   typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
   typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel_Iter Elf_Rel_Iter;
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela_Iter Elf_Rela_Iter;
 
   enum { TP_OFFSET = 0x7000, DTP_OFFSET = 0x8000 };
 
+  static const bool _isMips64EL =
+      ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+
   llvm::Optional<int64_t> _gp0;
   llvm::Optional<uint64_t> _tpOff;
   llvm::Optional<uint64_t> _dtpOff;
@@ -200,19 +231,30 @@ private:
   }
 
   void createRelocationReferences(const Elf_Sym *symbol,
+                                  ArrayRef<uint8_t> content,
+                                  range<Elf_Rela_Iter> rels) override {
+    const auto value = this->getSymbolValue(symbol);
+    for (const auto &rel : rels) {
+      if (rel.r_offset < value || value + content.size() <= rel.r_offset)
+        continue;
+      auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, rel);
+      this->addReferenceToSymbol(r, symbol);
+      this->_references.push_back(r);
+    }
+  }
+
+  void createRelocationReferences(const Elf_Sym *symbol,
                                   ArrayRef<uint8_t> symContent,
                                   ArrayRef<uint8_t> secContent,
                                   range<Elf_Rel_Iter> rels) override {
+    const auto value = this->getSymbolValue(symbol);
     for (Elf_Rel_Iter rit = rels.begin(), eit = rels.end(); rit != eit; ++rit) {
-      if (rit->r_offset < symbol->st_value ||
-          symbol->st_value + symContent.size() <= rit->r_offset)
+      if (rit->r_offset < value || value + symContent.size() <= rit->r_offset)
         continue;
 
-      auto elfReference = new (this->_readerStorage) ELFReference<ELFT>(
-          rit->r_offset - symbol->st_value, this->kindArch(),
-          rit->getType(isMips64EL()), rit->getSymbol(isMips64EL()));
-      ELFFile<ELFT>::addReferenceToSymbol(elfReference, symbol);
-      this->_references.push_back(elfReference);
+      auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, *rit);
+      this->addReferenceToSymbol(r, symbol);
+      this->_references.push_back(r);
 
       auto addend = readAddend(*rit, secContent);
       auto pairRelType = getPairRelocation(*rit);
@@ -234,11 +276,11 @@ private:
     const auto &rh =
         this->_ctx.template getTargetHandler<ELFT>().getRelocationHandler();
     return static_cast<const MipsRelocationHandler &>(rh)
-        .readAddend(ri.getType(isMips64EL()), content.data() + ri.r_offset);
+        .readAddend(getPrimaryType(ri), content.data() + ri.r_offset);
   }
 
   uint32_t getPairRelocation(const Elf_Rel &rel) const {
-    switch (rel.getType(isMips64EL())) {
+    switch (getPrimaryType(rel)) {
     case llvm::ELF::R_MIPS_HI16:
       return llvm::ELF::R_MIPS_LO16;
     case llvm::ELF::R_MIPS_PCHI16:
@@ -263,14 +305,16 @@ private:
   Elf_Rel_Iter findMatchingRelocation(uint32_t pairRelType, Elf_Rel_Iter rit,
                                       Elf_Rel_Iter eit) const {
     return std::find_if(rit, eit, [&](const Elf_Rel &rel) {
-      return rel.getType(isMips64EL()) == pairRelType &&
-             rel.getSymbol(isMips64EL()) == rit->getSymbol(isMips64EL());
+      return getPrimaryType(rel) == pairRelType &&
+             rel.getSymbol(_isMips64EL) == rit->getSymbol(_isMips64EL);
     });
   }
 
-  bool isMips64EL() const { return this->_objFile->isMips64EL(); }
+  static uint8_t getPrimaryType(const Elf_Rel &rel) {
+    return rel.getType(_isMips64EL) & 0xff;
+  }
   bool isLocalBinding(const Elf_Rel &rel) const {
-    return this->_objFile->getSymbol(rel.getSymbol(isMips64EL()))
+    return this->_objFile->getSymbol(rel.getSymbol(_isMips64EL))
                ->getBinding() == llvm::ELF::STB_LOCAL;
   }
 };

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=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Tue Mar 24 04:57:05 2015
@@ -230,18 +230,16 @@ static uint32_t relocGOTOfst(uint64_t S,
 /// \brief R_MIPS_GPREL16
 /// local: sign-extend(A) + S + GP0 - GP
 /// external: sign-extend(A) + S - GP
-static uint32_t relocGPRel16(uint64_t S, int64_t A, uint64_t GP) {
+static uint64_t relocGPRel16(uint64_t S, int64_t A, uint64_t GP) {
   // We added GP0 to addendum for a local symbol during a Relocation pass.
-  int32_t result = llvm::SignExtend32<16>(A) + S - GP;
-  return result;
+  return llvm::SignExtend32<16>(A) + S - GP;
 }
 
 /// \brief R_MIPS_GPREL32
 /// local: rel32 A + S + GP0 - GP (truncate)
-static uint32_t relocGPRel32(uint64_t S, int64_t A, uint64_t GP) {
+static uint64_t relocGPRel32(uint64_t S, int64_t A, uint64_t GP) {
   // We added GP0 to addendum for a local symbol during a Relocation pass.
-  int32_t result = A + S - GP;
-  return result;
+  return A + S - GP;
 }
 
 /// \brief R_MIPS_PC18_S3
@@ -556,7 +554,17 @@ std::error_code RelocationHandler<ELFT>:
   if (auto ec = res.getError())
     return ec;
 
-  auto params = getRelocationParams(ref.kindValue());
+  Reference::KindValue op = ref.kindValue();
+
+  // FIXME (simon): Handle r_ssym value.
+  for (auto tag = (ref.tag() & 0xffff); tag & 0xff; tag >>= 8) {
+    op = tag & 0xff;
+    res = calculateRelocation(op, *res, 0, relAddr, gpAddr, isGpDisp, jumpMode);
+    if (auto ec = res.getError())
+      return ec;
+  }
+
+  auto params = getRelocationParams(op);
   uint64_t ins = relocRead<ELFT>(params, location);
 
   if (auto ec = adjustJumpOpCode(ins, tgtAddr, jumpMode))

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=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Tue Mar 24 04:57:05 2015
@@ -435,6 +435,8 @@ void RelocationPass<ELFT>::perform(std::
     if (!isDynamic(ref->target()) || hasPLTEntry(ref->target()))
       continue;
     ref->setKindValue(R_MIPS_REL32);
+    if (ELFT::Is64Bits)
+      static_cast<MipsELFReference<ELFT> *>(ref)->setTag(R_MIPS_64);
     if (!isLocalCall(ref->target()))
       getGlobalGOTEntry(ref->target());
   }

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=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Tue Mar 24 04:57:05 2015
@@ -131,6 +131,37 @@ private:
   std::unordered_map<const Atom *, const AtomLayout *> _pltLayoutMap;
 };
 
+template <class ELFT> class MipsRelocationTable : public RelocationTable<ELFT> {
+  typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
+  typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
+
+  static const bool _isMips64EL =
+      ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+
+public:
+  using RelocationTable<ELFT>::RelocationTable;
+
+protected:
+  void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
+                 const Reference &ref) override {
+    uint32_t rType = ref.kindValue() | (ref.tag() << 8);
+    r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType, _isMips64EL);
+    r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+    // The addend is used only by relative relocations
+    if (this->_context.isRelativeReloc(ref))
+      r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
+    else
+      r.r_addend = 0;
+  }
+
+  void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
+                const Reference &ref) override {
+    uint32_t rType = ref.kindValue() | (ref.tag() << 8);
+    r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType, _isMips64EL);
+    r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+  }
+};
+
 } // elf
 } // lld
 

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=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Tue Mar 24 04:57:05 2015
@@ -74,6 +74,14 @@ public:
                                                 contentPermissions);
   }
 
+protected:
+  unique_bump_ptr<RelocationTable<ELFT>>
+  createRelocationTable(StringRef name, int32_t order) override {
+    return unique_bump_ptr<RelocationTable<ELFT>>(
+        new (this->_allocator)
+            MipsRelocationTable<ELFT>(this->_context, name, order));
+  }
+
 private:
   MipsGOTSection<ELFT> *_gotSection;
   MipsPLTSection<ELFT> *_pltSection;

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Tue Mar 24 04:57:05 2015
@@ -1019,54 +1019,55 @@ public:
     uint8_t *chunkBuffer = buffer.getBufferStart();
     uint8_t *dest = chunkBuffer + this->fileOffset();
     for (const auto &rel : _relocs) {
-      if (this->_context.isRelaOutputFormat())
-        writeRela(writer, *reinterpret_cast<Elf_Rela *>(dest), *rel.first,
-                  *rel.second);
-      else
-        writeRel(writer, *reinterpret_cast<Elf_Rel *>(dest), *rel.first,
-                 *rel.second);
+      if (this->_context.isRelaOutputFormat()) {
+        auto &r = *reinterpret_cast<Elf_Rela *>(dest);
+        writeRela(writer, r, *rel.first, *rel.second);
+        DEBUG_WITH_TYPE("ELFRelocationTable",
+                        llvm::dbgs()
+                            << rel.second->kindValue() << " relocation at "
+                            << rel.first->name() << "@" << r.r_offset << " to "
+                            << rel.second->target()->name() << "@" << r.r_addend
+                            << "\n";);
+      } else {
+        auto &r = *reinterpret_cast<Elf_Rel *>(dest);
+        writeRel(writer, r, *rel.first, *rel.second);
+        DEBUG_WITH_TYPE("ELFRelocationTable",
+                        llvm::dbgs() << rel.second->kindValue()
+                                     << " relocation at " << rel.first->name()
+                                     << "@" << r.r_offset << " to "
+                                     << rel.second->target()->name() << "\n";);
+      }
       dest += this->_entSize;
     }
   }
 
-private:
-  std::vector<std::pair<const DefinedAtom *, const Reference *> > _relocs;
+protected:
   const DynamicSymbolTable<ELFT> *_symbolTable;
 
-  bool isMips64ELOutput() const {
-    return this->_context.getTriple().getArch() == llvm::Triple::mips64el;
-  }
-
-  void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
-                 const Reference &ref) {
-    uint32_t index =
-        _symbolTable ? _symbolTable->getSymbolTableIndex(ref.target())
-                     : (uint32_t)STN_UNDEF;
-    r.setSymbolAndType(index, ref.kindValue(), isMips64ELOutput());
+  virtual void writeRela(ELFWriter *writer, Elf_Rela &r,
+                         const DefinedAtom &atom, const Reference &ref) {
+    r.setSymbolAndType(getSymbolIndex(ref.target()), ref.kindValue(), false);
     r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
-    r.r_addend = 0;
     // The addend is used only by relative relocations
     if (this->_context.isRelativeReloc(ref))
       r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
-    DEBUG_WITH_TYPE("ELFRelocationTable",
-                    llvm::dbgs() << ref.kindValue() << " relocation at "
-                                 << atom.name() << "@" << r.r_offset << " to "
-                                 << ref.target()->name() << "@" << r.r_addend
-                                 << "\n";);
+    else
+      r.r_addend = 0;
   }
 
-  void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
-                const Reference &ref) {
-    uint32_t index =
-        _symbolTable ? _symbolTable->getSymbolTableIndex(ref.target())
-                     : (uint32_t)STN_UNDEF;
-    r.setSymbolAndType(index, ref.kindValue(), isMips64ELOutput());
+  virtual void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
+                        const Reference &ref) {
+    r.setSymbolAndType(getSymbolIndex(ref.target()), ref.kindValue(), false);
     r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
-    DEBUG_WITH_TYPE("ELFRelocationTable",
-                    llvm::dbgs() << ref.kindValue() << " relocation at "
-                                 << atom.name() << "@" << r.r_offset << " to "
-                                 << ref.target()->name() << "\n";);
   }
+
+  uint32_t getSymbolIndex(const Atom *a) {
+    return _symbolTable ? _symbolTable->getSymbolTableIndex(a)
+                        : (uint32_t)STN_UNDEF;
+  }
+
+private:
+  std::vector<std::pair<const DefinedAtom *, const Reference *> > _relocs;
 };
 
 template <class ELFT> class HashSection;

Modified: lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h (original)
+++ lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h Tue Mar 24 04:57:05 2015
@@ -225,6 +225,7 @@ struct NativeReferenceIvarsV2 {
   uint8_t   kindNamespace;
   uint8_t   kindArch;
   uint32_t  targetIndex;
+  uint32_t  tag;
 };
 
 

Modified: lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp Tue Mar 24 04:57:05 2015
@@ -241,6 +241,7 @@ public:
   Addend addend() const override;
   void setTarget(const Atom* newAtom) override;
   void setAddend(Addend a) override;
+  uint32_t tag() const override;
 
 private:
   const File                    *_file;
@@ -978,6 +979,8 @@ inline void NativeReferenceV2::setAddend
   llvm_unreachable("setAddend() not supported");
 }
 
+uint32_t NativeReferenceV2::tag() const { return _ivarData->tag; }
+
 } // end namespace native
 
 namespace {

Modified: lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp Tue Mar 24 04:57:05 2015
@@ -448,6 +448,7 @@ private:
       nref.kindValue = ref->kindValue();
       nref.targetIndex = this->getTargetIndex(ref->target());
       nref.addend = ref->addend();
+      nref.tag = ref->tag();
       _referencesV2.push_back(nref);
     }
     refsCount = _referencesV2.size() - startRefSize;

Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=233057&r1=233056&r2=233057&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Tue Mar 24 04:57:05 2015
@@ -729,13 +729,14 @@ template <> struct MappingTraits<const l
     NormalizedReference(IO &io)
         : lld::Reference(lld::Reference::KindNamespace::all,
                          lld::Reference::KindArch::all, 0),
-          _target(nullptr), _targetName(), _offset(0), _addend(0) {}
+          _target(nullptr), _targetName(), _offset(0), _addend(0), _tag(0) {}
 
     NormalizedReference(IO &io, const lld::Reference *ref)
         : lld::Reference(ref->kindNamespace(), ref->kindArch(),
                          ref->kindValue()),
           _target(nullptr), _targetName(targetName(io, ref)),
-          _offset(ref->offsetInAtom()), _addend(ref->addend()) {
+          _offset(ref->offsetInAtom()), _addend(ref->addend()),
+          _tag(ref->tag()) {
       _mappedKind.ns = ref->kindNamespace();
       _mappedKind.arch = ref->kindArch();
       _mappedKind.value = ref->kindValue();
@@ -772,6 +773,7 @@ template <> struct MappingTraits<const l
     uint32_t         _offset;
     Addend           _addend;
     RefKind          _mappedKind;
+    uint32_t         _tag;
   };
 
   static void mapping(IO &io, const lld::Reference *&ref) {
@@ -782,6 +784,7 @@ template <> struct MappingTraits<const l
     io.mapOptional("offset", keys->_offset);
     io.mapOptional("target", keys->_targetName);
     io.mapOptional("addend", keys->_addend, (lld::Reference::Addend)0);
+    io.mapOptional("tag",    keys->_tag, 0u);
   }
 };
 

Added: lld/trunk/test/elf/Mips/n64-rel-chain.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/n64-rel-chain.test?rev=233057&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/n64-rel-chain.test (added)
+++ lld/trunk/test/elf/Mips/n64-rel-chain.test Tue Mar 24 04:57:05 2015
@@ -0,0 +1,134 @@
+# Check handling MIPS N64 ABI relocation "chains".
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
+# RUN: lld -flavor gnu -target mips64el -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mips64el -e T0 -o %t.exe %t-o.o %t.so
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# CHECK:      Contents of section .text:
+# CHECK-NEXT:  1200001d0 01000000 00000000 208e0000 00000000 ........ .......
+# CHECK-NEXT:  1200001e0 20800000 f8010000 28800000 00000000 .......(.......
+# CHECK:      Contents of section .pdr:
+# CHECK-NEXT:  0000 d0010020 e0010020 ... ...
+
+---
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    16
+    Size:            8
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+
+  Global:
+    - Name:            T1
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0
+      Size:            8
+
+---
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    16
+    Size:            32
+
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    8
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          LT1
+        Type:            R_MIPS_GPREL16
+        Type2:           R_MIPS_SUB
+        Type3:           R_MIPS_HI16
+      - Offset:          0x08
+        Symbol:          LT1
+        Type:            R_MIPS_GPREL16
+        Type2:           R_MIPS_SUB
+        Type3:           R_MIPS_LO16
+      - Offset:          0x10
+        Symbol:          .rodata
+        Type:            R_MIPS_GOT_PAGE
+        Addend:          8
+      - Offset:          0x14
+        Symbol:          .rodata
+        Type:            R_MIPS_GOT_OFST
+        Addend:          8
+      - Offset:          0x18
+        Symbol:          T1
+        Type:            R_MIPS_CALL16
+
+  - Name:            .pdr
+    Type:            SHT_PROGBITS
+    AddressAlign:    4
+    Size:            8
+
+  - Name:            .rela.pdr
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    8
+    Info:            .pdr
+    Relocations:
+      - Offset:          0x00
+        Symbol:          LT1
+        Type:            R_MIPS_32
+      - Offset:          0x04
+        Symbol:          T0
+        Type:            R_MIPS_32
+
+  - Name:            .rodata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    16
+    Size:            16
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+    - Name:            .rodata
+      Type:            STT_SECTION
+      Section:         .rodata
+    - Name:            .pdr
+      Type:            STT_SECTION
+      Section:         .pdr
+
+  Global:
+    - Name:            LT1
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x00
+      Size:            0x10
+    - Name:            T0
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x10
+      Size:            0x10
+    - Name:            T1
+...

Added: lld/trunk/test/elf/Mips/rel-dynamic-06-64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-06-64.test?rev=233057&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-06-64.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-06-64.test Tue Mar 24 04:57:05 2015
@@ -0,0 +1,101 @@
+# Conditions:
+#   a) Linking a shared library.
+#   b) The first relocation modifies a regular .text section.
+#   c) The second relocation modifies a .pdr section without SHF_ALLOC flag.
+# Check:
+#   a) There should be no PLT entries.
+#   b) Linker creates a single R_MIPS_REL32 relocation.
+#
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mips64el -shared -o %t.so %t.o
+# RUN: llvm-readobj -dt -r -s %t.so | FileCheck -check-prefix=CHECK %s
+
+# CHECK:     Sections [
+# CHECK:       Section {
+# CHECK-NOT:     Name: .plt ({{[0-9]+}})
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section (4) .rel.dyn {
+# CHECK-NEXT:     0x170 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T0 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: T1@ (4)
+# CHECK-NEXT:     Value: 0x174
+# CHECK-NEXT:     Size: 4
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Function (0x2)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text (0x5)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: T0@ (1)
+# CHECK-NEXT:     Value: 0x170
+# CHECK-NEXT:     Size: 4
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Function (0x2)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text (0x5)
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         8
+  AddressAlign: 16
+  Flags:        [SHF_EXECINSTR, SHF_ALLOC]
+
+- Name:         .rel.text
+  Type:         SHT_RELA
+  Info:         .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0
+      Symbol: T0
+      Type:   R_MIPS_64
+
+- Name:         .pdr
+  Type:         SHT_PROGBITS
+  Size:         8
+  AddressAlign: 16
+
+- Name:         .rel.pdr
+  Type:         SHT_RELA
+  Info:         .pdr
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0
+      Symbol: T1
+      Type:   R_MIPS_64
+
+Symbols:
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x0
+      Size:    4
+    - Name:    T1
+      Section: .text
+      Type:    STT_FUNC
+      Value:   4
+      Size:    4

Added: lld/trunk/test/elf/Mips/rel-dynamic-07-64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-07-64.test?rev=233057&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-07-64.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-07-64.test Tue Mar 24 04:57:05 2015
@@ -0,0 +1,261 @@
+# Conditions:
+#   a) Linking a shared library.
+#   b) There ars multiple R_MIPS_64 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 mips64el -shared -o %t1.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mips64el -shared --noinhibit-exec \
+# RUN:     -o %t2.so %t-o.o %t1.so
+# RUN: llvm-readobj -dt -r -sections %t2.so | FileCheck %s
+
+# CHECK:   Sections [
+# CHECK:     Section {
+# CHECK-NOT:   Name: .plt ({{[0-9]+}})
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section (4) .rel.dyn {
+# CHECK-NEXT:     0x2000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T0 0x0
+# CHECK-NEXT:     0x2000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T4 0x0
+# CHECK-NEXT:     0x2000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE D2 0x0
+# CHECK-NEXT:     0x2004 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T1 0x0
+# CHECK-NEXT:     0x2008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T2 0x0
+# CHECK-NEXT:     0x2004 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE D0 0x0
+# CHECK-NEXT:     0x2008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE D1 0x0
+# CHECK-NEXT:     0x2004 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE D4 0x0
+# CHECK-NEXT:     0x2008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE U1 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: T0@ (1)
+# CHECK-NEXT:     Value: 0x324
+# CHECK-NEXT:     Size: 8
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Function (0x2)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text (0x5)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: T4@ (7)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: None (0x0)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: D2@ (25)
+# 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@ (16)
+# 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@ (19)
+# 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: D0@ (4)
+# CHECK-NEXT:     Value: 0x2004
+# CHECK-NEXT:     Size: 8
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: Object (0x1)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .data (0x8)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: D1@ (22)
+# 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: D4@ (10)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: None (0x0)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: U1@ (13)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global (0x1)
+# CHECK-NEXT:     Type: None (0x0)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined (0x0)
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# so.o
+---
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  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:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  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.data
+  Type:         SHT_RELA
+  Info:         .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00      # T0 is a defined function
+      Symbol: T0
+      Type:   R_MIPS_64
+    - Offset: 0x04      # T1 is a function from shared lib
+      Symbol: T1
+      Type:   R_MIPS_64
+    - Offset: 0x08      # T2 has unknown type and defined in shared lib
+      Symbol: T2
+      Type:   R_MIPS_64
+    - Offset: 0x00      # T4 is an undefined function
+      Symbol: T4
+      Type:   R_MIPS_64
+    - Offset: 0x04      # D0 is a defined data object
+      Symbol: D0
+      Type:   R_MIPS_64
+    - Offset: 0x08      # D1 is a data object from shared lib
+      Symbol: D1
+      Type:   R_MIPS_64
+    - Offset: 0x00      # D2 has unknown type and defined in shared lib
+      Symbol: D2
+      Type:   R_MIPS_64
+    - Offset: 0x04      # D4 is an undefined data object
+      Symbol: D4
+      Type:   R_MIPS_64
+    - Offset: 0x08      # U1 is undefined and has unknown type
+      Symbol: U1
+      Type:   R_MIPS_64
+
+Symbols:
+  Local:
+    - Name:    LT0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0
+      Size:    4
+    - Name:    LD0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0
+      Size:    4
+
+  Global:
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x4
+      Size:    8
+    - 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-08-64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-dynamic-08-64.test?rev=233057&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-dynamic-08-64.test (added)
+++ lld/trunk/test/elf/Mips/rel-dynamic-08-64.test Tue Mar 24 04:57:05 2015
@@ -0,0 +1,233 @@
+# Conditions:
+#   a) Linking a non-shared executable file.
+#   b) There ars multiple R_MIPS_64/R_MIPS_HI16/R_MIPS_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 mips64el -shared -o %t.so %t-so.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
+# RUN: lld -flavor gnu -target mips64el -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:     0x120002000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE D2 0x0
+# CHECK-NEXT:     0x120002004 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T1 0x0
+# CHECK-NEXT:     0x120002008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T2 0x0
+# CHECK-NEXT:     0x120002008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE 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:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  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:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  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_RELA
+  Info:         .text
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00
+      Symbol: _gp_disp
+      Type:   R_MIPS_HI16
+    - Offset: 0x00
+      Symbol: _gp_disp
+      Type:   R_MIPS_LO16
+
+- Name:         .rel.data
+  Type:         SHT_RELA
+  Info:         .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x00      # LT0 is a locally defined function
+      Symbol: LT0
+      Type:   R_MIPS_64
+    - Offset: 0x00      # LD0 is a locally defined data object
+      Symbol: LD0
+      Type:   R_MIPS_64
+    - Offset: 0x00      # T0 is a defined function
+      Symbol: T0
+      Type:   R_MIPS_64
+    - Offset: 0x04      # T1 is a function from shared lib
+      Symbol: T1
+      Type:   R_MIPS_64
+    - Offset: 0x08      # T2 has unknown type and defined in shared lib
+      Symbol: T2
+      Type:   R_MIPS_64
+    - Offset: 0x00      # T4 is an undefined function
+      Symbol: T4
+      Type:   R_MIPS_64
+    - Offset: 0x04      # D0 is a defined data object
+      Symbol: D0
+      Type:   R_MIPS_64
+    - Offset: 0x08      # D1 is a data object from shared lib
+      Symbol: D1
+      Type:   R_MIPS_64
+    - Offset: 0x00      # D2 has unknown type and defined in shared lib
+      Symbol: D2
+      Type:   R_MIPS_64
+    - Offset: 0x04      # D4 is an undefined data object
+      Symbol: D4
+      Type:   R_MIPS_64
+    - Offset: 0x08      # U1 is undefined and has unknown type
+      Symbol: U1
+      Type:   R_MIPS_64
+
+Symbols:
+  Local:
+    - Name:    LT0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0
+      Size:    4
+    - Name:    LD0
+      Section: .data
+      Type:    STT_OBJECT
+      Value:   0
+      Size:    4
+
+  Global:
+    - Name:    _gp_disp
+      Type:    STT_OBJECT
+
+    - Name:    T0
+      Section: .text
+      Type:    STT_FUNC
+      Value:   0x4
+      Size:    8
+    - 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-gprel32-64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-gprel32-64.test?rev=233057&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-gprel32-64.test (added)
+++ lld/trunk/test/elf/Mips/rel-gprel32-64.test Tue Mar 24 04:57:05 2015
@@ -0,0 +1,70 @@
+# Check R_MIPS_GPREL32/R_MIPS_64 relocations handling.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mips64el -e T0 -o %t.exe %t.o
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# CHECK:      Contents of section .text:
+# CHECK-NEXT:  1200001a0 c871ffff ffffffff c871ffff c871ffff  .q.......q...q..
+# CHECK-NEXT:  1200001b0 c871ffff ffffffff 00000000 00000000  .q..............
+
+---
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    16
+    Size:            32
+
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    8
+    Info:            .text
+    Relocations:
+      - Offset:          0x00
+        Symbol:          LT1
+        Type:            R_MIPS_GPREL16
+        Type2:           R_MIPS_64
+        Type3:           R_MIPS_NONE
+      - Offset:          0x08
+        Symbol:          LT1
+        Type:            R_MIPS_GPREL16
+        Type2:           R_MIPS_64
+        Type3:           R_MIPS_NONE
+      - Offset:          0x0C
+        Symbol:          LT1
+        Type:            R_MIPS_GPREL32
+        Type2:           R_MIPS_64
+        Type3:           R_MIPS_NONE
+      - Offset:          0x10
+        Symbol:          LT1
+        Type:            R_MIPS_GPREL32
+        Type2:           R_MIPS_64
+        Type3:           R_MIPS_NONE
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+
+  Global:
+    - Name:            LT1
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x18
+      Size:            0x8
+    - Name:            T0
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0
+      Size:            0x18
+...





More information about the llvm-commits mailing list