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

Aaron Ballman aaron at aaronballman.com
Tue Mar 24 06:02:14 PDT 2015


On Tue, Mar 24, 2015 at 5:57 AM, Simon Atanasyan <simon at atanasyan.com> wrote:
> 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) {}

This code is causing a warning in MSVC because rel.getType() returns
an unsigned char, but you then >> by sizeof(unsigned char). Is that
intended?

1>e:\llvm\llvm\tools\lld\lib\readerwriter\elf\mips\MipsELFFile.h(104):
warning C4333: '>>' : right shift by too large amount, data loss
1>          e:\llvm\llvm\tools\lld\lib\readerwriter\elf\mips\MipsELFFile.h(100)
: while compiling class template member function
'lld::elf::MipsELFReference<ELFT>::MipsELFReference(uint64_t,const
llvm::object::Elf_Rel_Impl<ELFT,true> &)'
1>          with
1>          [
1>              ELFT=lld::elf::Mips32ELType
1>          ]
1>          e:\llvm\llvm\tools\lld\lib\readerwriter\elf\mips\MipsELFFile.h(240)
: see reference to function template instantiation
'lld::elf::MipsELFReference<ELFT>::MipsELFReference(uint64_t,const
llvm::object::Elf_Rel_Impl<ELFT,true> &)' being compiled
1>          with
1>          [
1>              ELFT=lld::elf::Mips32ELType
1>          ]
1>          E:\llvm\llvm\tools\lld\lib\ReaderWriter\ELF\Mips\MipsRelocationPass.cpp(439)
: see reference to class template instantiation
'lld::elf::MipsELFReference<ELFT>' being compiled
1>          with
1>          [
1>              ELFT=lld::elf::Mips32ELType
1>          ]
1>          E:\llvm\llvm\tools\lld\lib\ReaderWriter\ELF\Mips\MipsRelocationPass.cpp(421)
: while compiling class template member function 'void
`anonymous-namespace'::RelocationPass<lld::elf::Mips32ELType>::perform(std::unique_ptr<lld::MutableFile,std::default_delete<_Ty>>
&)'
1>          with
1>          [
1>              _Ty=lld::MutableFile
1>          ]
1>          D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\type_traits(475) : see reference to class template
instantiation '`anonymous-namespace'::RelocationPass<lld::elf::Mips32ELType>'
being compiled
1>          D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\memory(1393) : see reference to class template
instantiation 'std::is_convertible<`anonymous-namespace'::RelocationPass<lld::elf::Mips32ELType>
,lld::Pass *>' being compiled

> +
> +  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) {}

Same here as above.

~Aaron

> +
> +  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
> +...
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list