[lld] r238310 - [Mips] Move member function definitions to cpp files

Simon Atanasyan simon at atanasyan.com
Wed May 27 04:56:15 PDT 2015


Author: atanasyan
Date: Wed May 27 06:56:15 2015
New Revision: 238310

URL: http://llvm.org/viewvc/llvm-project?rev=238310&view=rev
Log:
[Mips] Move member function definitions to cpp files

No functional changes.

Added:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
      - copied, changed from r238304, lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
Removed:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt Wed May 27 06:56:15 2015
@@ -1,11 +1,14 @@
 add_llvm_library(lldMipsELFTarget
   MipsCtorsOrderPass.cpp
+  MipsELFFile.cpp
   MipsELFFlagsMerger.cpp
+  MipsELFWriters.cpp
   MipsLinkingContext.cpp
   MipsRelocationHandler.cpp
   MipsRelocationPass.cpp
-  MipsTargetHandler32EL.cpp
-  MipsTargetHandler64EL.cpp
+  MipsSectionChunks.cpp
+  MipsTargetHandler.cpp
+  MipsTargetLayout.cpp
   LINK_LIBS
     lldELF
     lldReaderWriter

Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (removed)
@@ -1,117 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h ---------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_LIBRARY_WRITER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_LIBRARY_WRITER_H
-
-#include "DynamicLibraryWriter.h"
-#include "MipsDynamicTable.h"
-#include "MipsELFWriters.h"
-#include "MipsLinkingContext.h"
-#include "MipsSectionChunks.h"
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT> class MipsSymbolTable;
-template <typename ELFT> class MipsDynamicSymbolTable;
-template <typename ELFT> class MipsTargetLayout;
-
-template <class ELFT>
-class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
-public:
-  MipsDynamicLibraryWriter(MipsLinkingContext &ctx,
-                           MipsTargetLayout<ELFT> &layout);
-
-protected:
-  // Add any runtime files and their atoms to the output
-  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
-  void finalizeDefaultAtomValues() override;
-  void createDefaultSections() override;
-
-  std::error_code setELFHeader() override {
-    DynamicLibraryWriter<ELFT>::setELFHeader();
-    _writeHelper.setELFHeader(*this->_elfHeader);
-    return std::error_code();
-  }
-
-  unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
-  unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
-  unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
-  MipsELFWriter<ELFT> _writeHelper;
-  MipsTargetLayout<ELFT> &_targetLayout;
-  unique_bump_ptr<Section<ELFT>> _reginfo;
-};
-
-template <class ELFT>
-MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
-    MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
-    : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
-      _targetLayout(layout) {}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
-    std::vector<std::unique_ptr<File>> &result) {
-  DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
-  result.push_back(_writeHelper.createRuntimeFile());
-}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
-  // Finalize the atom values that are part of the parent.
-  DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
-  _writeHelper.finalizeMipsRuntimeAtomValues();
-}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() {
-  DynamicLibraryWriter<ELFT>::createDefaultSections();
-  const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx);
-  const auto &mask = ctx.getMergedReginfoMask();
-  if (!mask.hasValue())
-    return;
-  if (ELFT::Is64Bits)
-    _reginfo = unique_bump_ptr<Section<ELFT>>(
-        new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask));
-  else
-    _reginfo = unique_bump_ptr<Section<ELFT>>(
-        new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask));
-  this->_layout.addSection(_reginfo.get());
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>>
-    MipsDynamicLibraryWriter<ELFT>::createSymbolTable() {
-  return unique_bump_ptr<SymbolTable<ELFT>>(
-      new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
-}
-
-/// \brief create dynamic table
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
-    MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
-  return unique_bump_ptr<DynamicTable<ELFT>>(
-      new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-/// \brief create dynamic symbol table
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
-    MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
-  return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
-      new (this->_alloc)
-          MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,284 @@
+//===- lib/ReaderWriter/ELF/MipsELFFile.cpp -------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsELFFile.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsELFDefinedAtom<ELFT>::MipsELFDefinedAtom(
+    const MipsELFFile<ELFT> &file, StringRef symbolName, StringRef sectionName,
+    const Elf_Sym *symbol, const Elf_Shdr *section,
+    ArrayRef<uint8_t> contentData, unsigned int referenceStart,
+    unsigned int referenceEnd, std::vector<ELFReference<ELFT> *> &referenceList)
+    : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
+                           contentData, referenceStart, referenceEnd,
+                           referenceList) {}
+
+template <class ELFT>
+const MipsELFFile<ELFT> &MipsELFDefinedAtom<ELFT>::file() const {
+  return static_cast<const MipsELFFile<ELFT> &>(this->_owningFile);
+}
+
+template <class ELFT>
+DefinedAtom::CodeModel MipsELFDefinedAtom<ELFT>::codeModel() const {
+  switch (this->_symbol->st_other & llvm::ELF::STO_MIPS_MIPS16) {
+  case llvm::ELF::STO_MIPS_MIPS16:
+    return DefinedAtom::codeMips16;
+  case llvm::ELF::STO_MIPS_PIC:
+    return DefinedAtom::codeMipsPIC;
+  case llvm::ELF::STO_MIPS_MICROMIPS:
+    return DefinedAtom::codeMipsMicro;
+  case llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC:
+    return DefinedAtom::codeMipsMicroPIC;
+  default:
+    return DefinedAtom::codeNA;
+  }
+}
+
+template class MipsELFDefinedAtom<ELF32LE>;
+template class MipsELFDefinedAtom<ELF64LE>;
+
+template <class ELFT> static bool isMips64EL() {
+  return ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+}
+
+template <class ELFT, bool isRela>
+static uint32_t
+extractTag(const llvm::object::Elf_Rel_Impl<ELFT, isRela> &rel) {
+  return (rel.getType(isMips64EL<ELFT>()) & 0xffffff00) >> 8;
+}
+
+template <class ELFT>
+MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rela &rel)
+    : ELFReference<ELFT>(&rel, rel.r_offset - symValue,
+                         Reference::KindArch::Mips,
+                         rel.getType(isMips64EL<ELFT>()) & 0xff,
+                         rel.getSymbol(isMips64EL<ELFT>())),
+      _tag(extractTag(rel)) {}
+
+template <class ELFT>
+MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rel &rel)
+    : ELFReference<ELFT>(rel.r_offset - symValue, Reference::KindArch::Mips,
+                         rel.getType(isMips64EL<ELFT>()) & 0xff,
+                         rel.getSymbol(isMips64EL<ELFT>())),
+      _tag(extractTag(rel)) {}
+
+template class MipsELFReference<ELF32LE>;
+template class MipsELFReference<ELF64LE>;
+
+template <class ELFT>
+MipsELFFile<ELFT>::MipsELFFile(std::unique_ptr<MemoryBuffer> mb,
+                               ELFLinkingContext &ctx)
+    : ELFFile<ELFT>(std::move(mb), ctx) {}
+
+template <class ELFT> bool MipsELFFile<ELFT>::isPIC() const {
+  return this->_objFile->getHeader()->e_flags & llvm::ELF::EF_MIPS_PIC;
+}
+
+template <class ELFT> std::error_code MipsELFFile<ELFT>::doParse() {
+  if (std::error_code ec = ELFFile<ELFT>::doParse())
+    return ec;
+  // Retrieve some auxiliary data like GP value, TLS section address etc
+  // from the object file.
+  return readAuxData();
+}
+
+template <class ELFT>
+ELFDefinedAtom<ELFT> *MipsELFFile<ELFT>::createDefinedAtom(
+    StringRef symName, StringRef sectionName, const Elf_Sym *sym,
+    const Elf_Shdr *sectionHdr, ArrayRef<uint8_t> contentData,
+    unsigned int referenceStart, unsigned int referenceEnd,
+    std::vector<ELFReference<ELFT> *> &referenceList) {
+  return new (this->_readerStorage) MipsELFDefinedAtom<ELFT>(
+      *this, symName, sectionName, sym, sectionHdr, contentData, referenceStart,
+      referenceEnd, referenceList);
+}
+
+template <class ELFT>
+const typename MipsELFFile<ELFT>::Elf_Shdr *
+MipsELFFile<ELFT>::findSectionByType(uint64_t type) const {
+  for (const Elf_Shdr &section : this->_objFile->sections())
+    if (section.sh_type == type)
+      return §ion;
+  return nullptr;
+}
+
+template <class ELFT>
+const typename MipsELFFile<ELFT>::Elf_Shdr *
+MipsELFFile<ELFT>::findSectionByFlags(uint64_t flags) const {
+  for (const Elf_Shdr &section : this->_objFile->sections())
+    if (section.sh_flags & flags)
+      return §ion;
+  return nullptr;
+}
+
+template <class ELFT>
+ErrorOr<const typename MipsELFFile<ELFT>::Elf_Mips_RegInfo *>
+MipsELFFile<ELFT>::findRegInfoSec() const {
+  using namespace llvm::ELF;
+  if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
+    auto contents = this->getSectionContents(sec);
+    if (std::error_code ec = contents.getError())
+      return ec;
+
+    ArrayRef<uint8_t> raw = contents.get();
+    while (!raw.empty()) {
+      if (raw.size() < sizeof(Elf_Mips_Options))
+        return make_dynamic_error_code(
+            StringRef("Invalid size of MIPS_OPTIONS section"));
+
+      const auto *opt = reinterpret_cast<const Elf_Mips_Options *>(raw.data());
+      if (opt->kind == ODK_REGINFO)
+        return &opt->getRegInfo();
+      raw = raw.slice(opt->size);
+    }
+  } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
+    auto contents = this->getSectionContents(sec);
+    if (std::error_code ec = contents.getError())
+      return ec;
+
+    ArrayRef<uint8_t> raw = contents.get();
+    if (raw.size() != sizeof(Elf_Mips_RegInfo))
+      return make_dynamic_error_code(
+          StringRef("Invalid size of MIPS_REGINFO section"));
+
+    return reinterpret_cast<const Elf_Mips_RegInfo *>(raw.data());
+  }
+  return nullptr;
+}
+
+template <class ELFT> std::error_code MipsELFFile<ELFT>::readAuxData() {
+  using namespace llvm::ELF;
+  if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
+    _tpOff = sec->sh_addr + TP_OFFSET;
+    _dtpOff = sec->sh_addr + DTP_OFFSET;
+  }
+
+  auto &ctx = static_cast<MipsLinkingContext &>(this->_ctx);
+
+  ErrorOr<const Elf_Mips_RegInfo *> regInfoSec = findRegInfoSec();
+  if (auto ec = regInfoSec.getError())
+    return ec;
+  if (const Elf_Mips_RegInfo *regInfo = regInfoSec.get()) {
+    ctx.mergeReginfoMask(*regInfo);
+    _gp0 = regInfo->ri_gp_value;
+  }
+
+  const Elf_Ehdr *hdr = this->_objFile->getHeader();
+  if (std::error_code ec = ctx.mergeElfFlags(hdr->e_flags))
+    return ec;
+
+  return std::error_code();
+}
+
+template <class ELFT>
+void MipsELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
+                                                   ArrayRef<uint8_t> content,
+                                                   range<Elf_Rela_Iter> rels) {
+  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);
+  }
+}
+
+template <class ELFT>
+void MipsELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
+                                                   ArrayRef<uint8_t> symContent,
+                                                   ArrayRef<uint8_t> secContent,
+                                                   range<Elf_Rel_Iter> rels) {
+  const auto value = this->getSymbolValue(symbol);
+  for (Elf_Rel_Iter rit = rels.begin(), eit = rels.end(); rit != eit; ++rit) {
+    if (rit->r_offset < value || value + symContent.size() <= rit->r_offset)
+      continue;
+
+    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);
+    if (pairRelType != llvm::ELF::R_MIPS_NONE) {
+      addend <<= 16;
+      auto mit = findMatchingRelocation(pairRelType, rit, eit);
+      if (mit != eit)
+        addend += int16_t(readAddend(*mit, secContent));
+      else
+        // FIXME (simon): Show detailed warning.
+        llvm::errs() << "lld warning: cannot matching LO16 relocation\n";
+    }
+    this->_references.back()->setAddend(addend);
+  }
+}
+
+template <class ELFT>
+static uint8_t
+getPrimaryType(const llvm::object::Elf_Rel_Impl<ELFT, false> &rel) {
+  return rel.getType(isMips64EL<ELFT>()) & 0xff;
+}
+
+template <class ELFT>
+Reference::Addend
+MipsELFFile<ELFT>::readAddend(const Elf_Rel &ri,
+                              const ArrayRef<uint8_t> content) const {
+  return readMipsRelocAddend(getPrimaryType(ri), content.data() + ri.r_offset);
+}
+
+template <class ELFT>
+uint32_t MipsELFFile<ELFT>::getPairRelocation(const Elf_Rel &rel) const {
+  switch (getPrimaryType(rel)) {
+  case llvm::ELF::R_MIPS_HI16:
+    return llvm::ELF::R_MIPS_LO16;
+  case llvm::ELF::R_MIPS_PCHI16:
+    return llvm::ELF::R_MIPS_PCLO16;
+  case llvm::ELF::R_MIPS_GOT16:
+    if (isLocalBinding(rel))
+      return llvm::ELF::R_MIPS_LO16;
+    break;
+  case llvm::ELF::R_MICROMIPS_HI16:
+    return llvm::ELF::R_MICROMIPS_LO16;
+  case llvm::ELF::R_MICROMIPS_GOT16:
+    if (isLocalBinding(rel))
+      return llvm::ELF::R_MICROMIPS_LO16;
+    break;
+  default:
+    // Nothing to do.
+    break;
+  }
+  return llvm::ELF::R_MIPS_NONE;
+}
+
+template <class ELFT>
+typename MipsELFFile<ELFT>::Elf_Rel_Iter
+MipsELFFile<ELFT>::findMatchingRelocation(uint32_t pairRelType,
+                                          Elf_Rel_Iter rit,
+                                          Elf_Rel_Iter eit) const {
+  return std::find_if(rit, eit, [&](const Elf_Rel &rel) {
+    return getPrimaryType(rel) == pairRelType &&
+           rel.getSymbol(isMips64EL<ELFT>()) ==
+               rit->getSymbol(isMips64EL<ELFT>());
+  });
+}
+
+template <class ELFT>
+bool MipsELFFile<ELFT>::isLocalBinding(const Elf_Rel &rel) const {
+  return this->_objFile->getSymbol(rel.getSymbol(isMips64EL<ELFT>()))
+             ->getBinding() == llvm::ELF::STB_LOCAL;
+}
+
+template class MipsELFFile<ELF32LE>;
+template class MipsELFFile<ELF64LE>;
+
+} // elf
+} // lld

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=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Wed May 27 06:56:15 2015
@@ -30,70 +30,32 @@ public:
                      StringRef sectionName, const Elf_Sym *symbol,
                      const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
                      unsigned int referenceStart, unsigned int referenceEnd,
-                     std::vector<ELFReference<ELFT> *> &referenceList)
-      : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
-                             contentData, referenceStart, referenceEnd,
-                             referenceList) {}
-
-  const MipsELFFile<ELFT>& file() const override {
-    return static_cast<const MipsELFFile<ELFT> &>(this->_owningFile);
-  }
-
-  DefinedAtom::CodeModel codeModel() const override {
-    switch (this->_symbol->st_other & llvm::ELF::STO_MIPS_MIPS16) {
-    case llvm::ELF::STO_MIPS_MIPS16:
-      return DefinedAtom::codeMips16;
-    case llvm::ELF::STO_MIPS_PIC:
-      return DefinedAtom::codeMipsPIC;
-    case llvm::ELF::STO_MIPS_MICROMIPS:
-      return DefinedAtom::codeMipsMicro;
-    case llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC:
-      return DefinedAtom::codeMipsMicroPIC;
-    default:
-      return DefinedAtom::codeNA;
-    }
-  }
+                     std::vector<ELFReference<ELFT> *> &referenceList);
+
+  const MipsELFFile<ELFT>& file() const override;
+  DefinedAtom::CodeModel codeModel() const override;
 };
 
 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(extractTag(rel)) {}
-
-  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(extractTag(rel)) {}
+  MipsELFReference(uint64_t symValue, const Elf_Rela &rel);
+  MipsELFReference(uint64_t symValue, const Elf_Rel &rel);
 
   uint32_t tag() const override { return _tag; }
   void setTag(uint32_t tag) { _tag = tag; }
 
 private:
   uint32_t _tag;
-
-  template <class R> static uint32_t extractTag(const R &rel) {
-    return (rel.getType(_isMips64EL) & 0xffffff00) >> 8;
-  }
 };
 
 template <class ELFT> class MipsELFFile : public ELFFile<ELFT> {
 public:
-  MipsELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
-      : ELFFile<ELFT>(std::move(mb), ctx) {}
+  MipsELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx);
 
-  bool isPIC() const {
-    return this->_objFile->getHeader()->e_flags & llvm::ELF::EF_MIPS_PIC;
-  }
+  bool isPIC() const;
 
   /// \brief gp register value stored in the .reginfo section.
   int64_t getGP0() const { return _gp0; }
@@ -103,13 +65,7 @@ public:
   uint64_t getDTPOffset() const { return _dtpOff; }
 
 protected:
-  std::error_code doParse() override {
-    if (std::error_code ec = ELFFile<ELFT>::doParse())
-      return ec;
-    // Retrieve some auxiliary data like GP value, TLS section address etc
-    // from the object file.
-    return readAuxData();
-  }
+  std::error_code doParse() override;
 
 private:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
@@ -120,9 +76,6 @@ private:
 
   enum { TP_OFFSET = 0x7000, DTP_OFFSET = 0x8000 };
 
-  static const bool _isMips64EL =
-      ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
-
   int64_t _gp0 = 0;
   uint64_t _tpOff = 0;
   uint64_t _dtpOff = 0;
@@ -132,173 +85,36 @@ private:
                     const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
                     ArrayRef<uint8_t> contentData, unsigned int referenceStart,
                     unsigned int referenceEnd,
-                    std::vector<ELFReference<ELFT> *> &referenceList) override {
-    return new (this->_readerStorage) MipsELFDefinedAtom<ELFT>(
-        *this, symName, sectionName, sym, sectionHdr, contentData,
-        referenceStart, referenceEnd, referenceList);
-  }
-
-  const Elf_Shdr *findSectionByType(uint64_t type) const {
-    for (const Elf_Shdr &section : this->_objFile->sections())
-      if (section.sh_type == type)
-        return §ion;
-    return nullptr;
-  }
-
-  const Elf_Shdr *findSectionByFlags(uint64_t flags) const {
-    for (const Elf_Shdr &section : this->_objFile->sections())
-      if (section.sh_flags & flags)
-        return §ion;
-    return nullptr;
-  }
-
-  typedef typename llvm::object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
-  typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
-  typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
-
-  ErrorOr<const Elf_Mips_RegInfo *> findRegInfoSec() const {
-    using namespace llvm::ELF;
-    if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
-      auto contents = this->getSectionContents(sec);
-      if (std::error_code ec = contents.getError())
-        return ec;
-
-      ArrayRef<uint8_t> raw = contents.get();
-      while (!raw.empty()) {
-        if (raw.size() < sizeof(Elf_Mips_Options))
-          return make_dynamic_error_code(
-              StringRef("Invalid size of MIPS_OPTIONS section"));
-
-        const auto *opt =
-            reinterpret_cast<const Elf_Mips_Options *>(raw.data());
-        if (opt->kind == ODK_REGINFO)
-          return &opt->getRegInfo();
-        raw = raw.slice(opt->size);
-      }
-    } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
-      auto contents = this->getSectionContents(sec);
-      if (std::error_code ec = contents.getError())
-        return ec;
-
-      ArrayRef<uint8_t> raw = contents.get();
-      if (raw.size() != sizeof(Elf_Mips_RegInfo))
-        return make_dynamic_error_code(
-            StringRef("Invalid size of MIPS_REGINFO section"));
-
-      return reinterpret_cast<const Elf_Mips_RegInfo *>(raw.data());
-    }
-    return nullptr;
-  }
-
-  std::error_code readAuxData() {
-    using namespace llvm::ELF;
-    if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
-      _tpOff = sec->sh_addr + TP_OFFSET;
-      _dtpOff = sec->sh_addr + DTP_OFFSET;
-    }
-
-    auto &ctx = static_cast<MipsLinkingContext &>(this->_ctx);
-
-    ErrorOr<const Elf_Mips_RegInfo *> regInfoSec = findRegInfoSec();
-    if (auto ec = regInfoSec.getError())
-      return ec;
-    if (const Elf_Mips_RegInfo *regInfo = regInfoSec.get()) {
-      ctx.mergeReginfoMask(*regInfo);
-      _gp0 = regInfo->ri_gp_value;
-    }
-
-    const Elf_Ehdr *hdr = this->_objFile->getHeader();
-    if (std::error_code ec = ctx.mergeElfFlags(hdr->e_flags))
-      return ec;
-
-    return std::error_code();
-  }
+                    std::vector<ELFReference<ELFT> *> &referenceList) override;
 
   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);
-    }
-  }
-
+                                  range<Elf_Rela_Iter> rels) override;
   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 < value || value + symContent.size() <= rit->r_offset)
-        continue;
-
-      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);
-      if (pairRelType != llvm::ELF::R_MIPS_NONE) {
-        addend <<= 16;
-        auto mit = findMatchingRelocation(pairRelType, rit, eit);
-        if (mit != eit)
-          addend += int16_t(readAddend(*mit, secContent));
-        else
-          // FIXME (simon): Show detailed warning.
-          llvm::errs() << "lld warning: cannot matching LO16 relocation\n";
-      }
-      this->_references.back()->setAddend(addend);
-    }
-  }
+                                  range<Elf_Rel_Iter> rels) override;
+
+  const Elf_Shdr *findSectionByType(uint64_t type) const;
+  const Elf_Shdr *findSectionByFlags(uint64_t flags) const;
+
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
+  typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
+  typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
+
+  ErrorOr<const Elf_Mips_RegInfo *> findRegInfoSec() const;
+
+  std::error_code readAuxData();
 
   Reference::Addend readAddend(const Elf_Rel &ri,
-                               const ArrayRef<uint8_t> content) const {
-    return readMipsRelocAddend(getPrimaryType(ri),
-                               content.data() + ri.r_offset);
-  }
-
-  uint32_t getPairRelocation(const Elf_Rel &rel) const {
-    switch (getPrimaryType(rel)) {
-    case llvm::ELF::R_MIPS_HI16:
-      return llvm::ELF::R_MIPS_LO16;
-    case llvm::ELF::R_MIPS_PCHI16:
-      return llvm::ELF::R_MIPS_PCLO16;
-    case llvm::ELF::R_MIPS_GOT16:
-      if (isLocalBinding(rel))
-        return llvm::ELF::R_MIPS_LO16;
-      break;
-    case llvm::ELF::R_MICROMIPS_HI16:
-      return llvm::ELF::R_MICROMIPS_LO16;
-    case llvm::ELF::R_MICROMIPS_GOT16:
-      if (isLocalBinding(rel))
-        return llvm::ELF::R_MICROMIPS_LO16;
-      break;
-    default:
-      // Nothing to do.
-      break;
-    }
-    return llvm::ELF::R_MIPS_NONE;
-  }
+                               const ArrayRef<uint8_t> content) const;
+
+  uint32_t getPairRelocation(const Elf_Rel &rel) const;
 
   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 getPrimaryType(rel) == pairRelType &&
-             rel.getSymbol(_isMips64EL) == rit->getSymbol(_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))
-               ->getBinding() == llvm::ELF::STB_LOCAL;
-  }
+                                      Elf_Rel_Iter eit) const;
+
+  bool isLocalBinding(const Elf_Rel &rel) const;
 };
 
 } // elf

Copied: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp (from r238304, lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp?p2=lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp&p1=lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h&r1=238304&r2=238310&rev=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp Wed May 27 06:56:15 2015
@@ -1,4 +1,4 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h -------------------===//
+//===- lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp -----------------------===//
 //
 //                             The LLVM Linker
 //
@@ -6,43 +6,141 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
 
-#include "ExecutableWriter.h"
 #include "MipsDynamicTable.h"
 #include "MipsELFWriters.h"
 #include "MipsLinkingContext.h"
+#include "MipsTargetHandler.h"
+#include "MipsTargetLayout.h"
+
+namespace {
+class MipsDynamicAtom : public lld::elf::DynamicAtom {
+public:
+  MipsDynamicAtom(const lld::File &f) : DynamicAtom(f) {}
+
+  ContentPermissions permissions() const override { return permR__; }
+};
+}
 
 namespace lld {
 namespace elf {
 
-template <typename ELFT> class MipsTargetLayout;
+template <class ELFT>
+MipsELFWriter<ELFT>::MipsELFWriter(MipsLinkingContext &ctx,
+                                   MipsTargetLayout<ELFT> &targetLayout)
+    : _ctx(ctx), _targetLayout(targetLayout) {}
 
 template <class ELFT>
-class MipsExecutableWriter : public ExecutableWriter<ELFT> {
-public:
-  MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
+void MipsELFWriter<ELFT>::setELFHeader(ELFHeader<ELFT> &elfHeader) {
+  elfHeader.e_version(1);
+  elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
+  elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
+  if (_targetLayout.findOutputSection(".got.plt"))
+    elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1);
+  else
+    elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
 
-protected:
-  void buildDynamicSymbolTable(const File &file) override;
+  elfHeader.e_flags(_ctx.getMergedELFFlags());
+}
 
-  // Add any runtime files and their atoms to the output
-  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
+template <class ELFT>
+void MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues() {
+  if (!_ctx.isDynamic())
+    return;
 
-  void finalizeDefaultAtomValues() override;
-  void createDefaultSections() override;
-  std::error_code setELFHeader() override;
-
-  unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
-  unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
-  unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
-  MipsELFWriter<ELFT> _writeHelper;
-  MipsTargetLayout<ELFT> &_targetLayout;
-  unique_bump_ptr<Section<ELFT>> _reginfo;
-};
+  auto gotSection = _targetLayout.findOutputSection(".got");
+  auto got = gotSection ? gotSection->virtualAddr() : 0;
+  auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
+
+  setAtomValue("_gp", gp);
+  setAtomValue("_gp_disp", gp);
+  setAtomValue("__gnu_local_gp", gp);
+}
+
+template <class ELFT>
+std::unique_ptr<RuntimeFile<ELFT>> MipsELFWriter<ELFT>::createRuntimeFile() {
+  auto file = llvm::make_unique<RuntimeFile<ELFT>>(_ctx, "Mips runtime file");
+  if (_ctx.isDynamic()) {
+    file->addAbsoluteAtom("_gp");
+    file->addAbsoluteAtom("_gp_disp");
+    file->addAbsoluteAtom("__gnu_local_gp");
+    file->addAtom(*new (file->allocator()) MipsDynamicAtom(*file));
+  }
+  return file;
+}
+
+template <class ELFT>
+void MipsELFWriter<ELFT>::setAtomValue(StringRef name, uint64_t value) {
+  AtomLayout *atom = _targetLayout.findAbsoluteAtom(name);
+  assert(atom);
+  atom->_virtualAddr = value;
+}
+
+template <class ELFT>
+MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
+    MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
+    : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
+      _targetLayout(layout) {}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+  result.push_back(_writeHelper.createRuntimeFile());
+}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+  DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+  _writeHelper.finalizeMipsRuntimeAtomValues();
+}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() {
+  DynamicLibraryWriter<ELFT>::createDefaultSections();
+  const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx);
+  const auto &mask = ctx.getMergedReginfoMask();
+  if (!mask.hasValue())
+    return;
+  if (ELFT::Is64Bits)
+    _reginfo = unique_bump_ptr<Section<ELFT>>(
+        new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask));
+  else
+    _reginfo = unique_bump_ptr<Section<ELFT>>(
+        new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask));
+  this->_layout.addSection(_reginfo.get());
+}
+
+template <class ELFT>
+std::error_code MipsDynamicLibraryWriter<ELFT>::setELFHeader() {
+  DynamicLibraryWriter<ELFT>::setELFHeader();
+  _writeHelper.setELFHeader(*this->_elfHeader);
+  return std::error_code();
+}
+
+template <class ELFT>
+unique_bump_ptr<SymbolTable<ELFT>>
+MipsDynamicLibraryWriter<ELFT>::createSymbolTable() {
+  return unique_bump_ptr<SymbolTable<ELFT>>(
+      new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
+}
+
+template <class ELFT>
+unique_bump_ptr<DynamicTable<ELFT>>
+MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
+  return unique_bump_ptr<DynamicTable<ELFT>>(
+      new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
+}
+
+template <class ELFT>
+unique_bump_ptr<DynamicSymbolTable<ELFT>>
+MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
+  return unique_bump_ptr<DynamicSymbolTable<ELFT>>(new (
+      this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
+}
+
+template class MipsDynamicLibraryWriter<ELF32LE>;
+template class MipsDynamicLibraryWriter<ELF64LE>;
 
 template <class ELFT>
 MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx,
@@ -140,7 +238,7 @@ template <class ELFT> void MipsExecutabl
 
 template <class ELFT>
 unique_bump_ptr<SymbolTable<ELFT>>
-    MipsExecutableWriter<ELFT>::createSymbolTable() {
+MipsExecutableWriter<ELFT>::createSymbolTable() {
   return unique_bump_ptr<SymbolTable<ELFT>>(
       new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
 }
@@ -148,7 +246,7 @@ unique_bump_ptr<SymbolTable<ELFT>>
 /// \brief create dynamic table
 template <class ELFT>
 unique_bump_ptr<DynamicTable<ELFT>>
-    MipsExecutableWriter<ELFT>::createDynamicTable() {
+MipsExecutableWriter<ELFT>::createDynamicTable() {
   return unique_bump_ptr<DynamicTable<ELFT>>(
       new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
 }
@@ -156,13 +254,13 @@ unique_bump_ptr<DynamicTable<ELFT>>
 /// \brief create dynamic symbol table
 template <class ELFT>
 unique_bump_ptr<DynamicSymbolTable<ELFT>>
-    MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
-  return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
-      new (this->_alloc)
-          MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
+MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
+  return unique_bump_ptr<DynamicSymbolTable<ELFT>>(new (
+      this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
 }
 
-} // namespace elf
-} // namespace lld
+template class MipsExecutableWriter<ELF32LE>;
+template class MipsExecutableWriter<ELF64LE>;
 
-#endif
+} // elf
+} // lld

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h Wed May 27 06:56:15 2015
@@ -9,6 +9,8 @@
 #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
 #define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
 
+#include "DynamicLibraryWriter.h"
+#include "ExecutableWriter.h"
 #include "MipsLinkingContext.h"
 
 namespace lld {
@@ -16,63 +18,71 @@ namespace elf {
 
 template <class ELFT> class MipsTargetLayout;
 
-class MipsDynamicAtom : public DynamicAtom {
+template <typename ELFT> class MipsELFWriter {
 public:
-  MipsDynamicAtom(const File &f) : DynamicAtom(f) {}
+  MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout);
+
+  void setELFHeader(ELFHeader<ELFT> &elfHeader);
+
+  void finalizeMipsRuntimeAtomValues();
 
-  ContentPermissions permissions() const override { return permR__; }
+  std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile();
+
+private:
+  MipsLinkingContext &_ctx;
+  MipsTargetLayout<ELFT> &_targetLayout;
+
+  void setAtomValue(StringRef name, uint64_t value);
 };
 
-template <typename ELFT> class MipsELFWriter {
+template <class ELFT>
+class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
 public:
-  MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout)
-      : _ctx(ctx), _targetLayout(targetLayout) {}
+  MipsDynamicLibraryWriter(MipsLinkingContext &ctx,
+                           MipsTargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
+
+  void finalizeDefaultAtomValues() override;
+  void createDefaultSections() override;
 
-  void setELFHeader(ELFHeader<ELFT> &elfHeader) {
-    elfHeader.e_version(1);
-    elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
-    elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
-    if (_targetLayout.findOutputSection(".got.plt"))
-      elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1);
-    else
-      elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
-
-    elfHeader.e_flags(_ctx.getMergedELFFlags());
-  }
-
-  void finalizeMipsRuntimeAtomValues() {
-    if (!_ctx.isDynamic())
-      return;
-
-    auto gotSection = _targetLayout.findOutputSection(".got");
-    auto got = gotSection ? gotSection->virtualAddr() : 0;
-    auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
-
-    setAtomValue("_gp", gp);
-    setAtomValue("_gp_disp", gp);
-    setAtomValue("__gnu_local_gp", gp);
-  }
-
-  std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile() {
-    auto file = llvm::make_unique<RuntimeFile<ELFT>>(_ctx, "Mips runtime file");
-    if (_ctx.isDynamic()) {
-      file->addAbsoluteAtom("_gp");
-      file->addAbsoluteAtom("_gp_disp");
-      file->addAbsoluteAtom("__gnu_local_gp");
-      file->addAtom(*new (file->allocator()) MipsDynamicAtom(*file));
-    }
-    return file;
-  }
+  std::error_code setELFHeader() override;
+
+  unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
+  unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
+  unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
 
 private:
-  MipsLinkingContext &_ctx;
+  MipsELFWriter<ELFT> _writeHelper;
   MipsTargetLayout<ELFT> &_targetLayout;
+  unique_bump_ptr<Section<ELFT>> _reginfo;
+};
+
+template <class ELFT>
+class MipsExecutableWriter : public ExecutableWriter<ELFT> {
+public:
+  MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
+
+protected:
+  void buildDynamicSymbolTable(const File &file) override;
 
-  void setAtomValue(StringRef name, uint64_t value) {
-    AtomLayout *atom = _targetLayout.findAbsoluteAtom(name);
-    assert(atom);
-    atom->_virtualAddr = value;
-  }
+  // Add any runtime files and their atoms to the output
+  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
+
+  void finalizeDefaultAtomValues() override;
+  void createDefaultSections() override;
+  std::error_code setELFHeader() override;
+
+  unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
+  unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
+  unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
+
+private:
+  MipsELFWriter<ELFT> _writeHelper;
+  MipsTargetLayout<ELFT> &_targetLayout;
+  unique_bump_ptr<Section<ELFT>> _reginfo;
 };
 
 } // elf

Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (removed)
@@ -1,168 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h -------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-#include "MipsDynamicTable.h"
-#include "MipsELFWriters.h"
-#include "MipsLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT> class MipsTargetLayout;
-
-template <class ELFT>
-class MipsExecutableWriter : public ExecutableWriter<ELFT> {
-public:
-  MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
-
-protected:
-  void buildDynamicSymbolTable(const File &file) override;
-
-  // Add any runtime files and their atoms to the output
-  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
-  void finalizeDefaultAtomValues() override;
-  void createDefaultSections() override;
-  std::error_code setELFHeader() override;
-
-  unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
-  unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
-  unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
-  MipsELFWriter<ELFT> _writeHelper;
-  MipsTargetLayout<ELFT> &_targetLayout;
-  unique_bump_ptr<Section<ELFT>> _reginfo;
-};
-
-template <class ELFT>
-MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx,
-                                                 MipsTargetLayout<ELFT> &layout)
-    : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
-      _targetLayout(layout) {}
-
-template <class ELFT>
-std::error_code MipsExecutableWriter<ELFT>::setELFHeader() {
-  std::error_code ec = ExecutableWriter<ELFT>::setELFHeader();
-  if (ec)
-    return ec;
-
-  StringRef entryName = this->_ctx.entrySymbolName();
-  if (const AtomLayout *al = this->_layout.findAtomLayoutByName(entryName)) {
-    const auto *ea = cast<DefinedAtom>(al->_atom);
-    if (ea->codeModel() == DefinedAtom::codeMipsMicro ||
-        ea->codeModel() == DefinedAtom::codeMipsMicroPIC)
-      // Adjust entry symbol value if this symbol is microMIPS encoded.
-      this->_elfHeader->e_entry(al->_virtualAddr | 1);
-  }
-
-  _writeHelper.setELFHeader(*this->_elfHeader);
-  return std::error_code();
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
-  // MIPS ABI requires to add to dynsym even undefined symbols
-  // if they have a corresponding entries in a global part of GOT.
-  for (auto sec : this->_layout.sections())
-    if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
-      for (const auto &atom : section->atoms()) {
-        if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) {
-          this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
-                                               atom->_virtualAddr, atom);
-          continue;
-        }
-
-        const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
-        if (!da)
-          continue;
-
-        if (da->dynamicExport() != DefinedAtom::dynamicExportAlways &&
-            !this->_ctx.isDynamicallyExportedSymbol(da->name()) &&
-            !(this->_ctx.shouldExportDynamic() &&
-              da->scope() == Atom::Scope::scopeGlobal))
-          continue;
-
-        this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
-                                             atom->_virtualAddr, atom);
-      }
-
-  for (const UndefinedAtom *a : file.undefined())
-    // FIXME (simon): Consider to move this check to the
-    // MipsELFUndefinedAtom class method. That allows to
-    // handle more complex coditions in the future.
-    if (_targetLayout.getGOTSection().hasGlobalGOTEntry(a))
-      this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
-
-  // Skip our immediate parent class method
-  // ExecutableWriter<ELFT>::buildDynamicSymbolTable because we replaced it
-  // with our own version. Call OutputELFWriter directly.
-  OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::createImplicitFiles(
-    std::vector<std::unique_ptr<File>> &result) {
-  ExecutableWriter<ELFT>::createImplicitFiles(result);
-  result.push_back(_writeHelper.createRuntimeFile());
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
-  // Finalize the atom values that are part of the parent.
-  ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
-  _writeHelper.finalizeMipsRuntimeAtomValues();
-}
-
-template <class ELFT> void MipsExecutableWriter<ELFT>::createDefaultSections() {
-  ExecutableWriter<ELFT>::createDefaultSections();
-  const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx);
-  const auto &mask = ctx.getMergedReginfoMask();
-  if (!mask.hasValue())
-    return;
-  if (ELFT::Is64Bits)
-    _reginfo = unique_bump_ptr<Section<ELFT>>(
-        new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask));
-  else
-    _reginfo = unique_bump_ptr<Section<ELFT>>(
-        new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask));
-  this->_layout.addSection(_reginfo.get());
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>>
-    MipsExecutableWriter<ELFT>::createSymbolTable() {
-  return unique_bump_ptr<SymbolTable<ELFT>>(
-      new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
-}
-
-/// \brief create dynamic table
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
-    MipsExecutableWriter<ELFT>::createDynamicTable() {
-  return unique_bump_ptr<DynamicTable<ELFT>>(
-      new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-/// \brief create dynamic symbol table
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
-    MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
-  return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
-      new (this->_alloc)
-          MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Wed May 27 06:56:15 2015
@@ -28,9 +28,9 @@ static std::unique_ptr<TargetHandler> cr
                                                    MipsLinkingContext &ctx) {
   switch (triple.getArch()) {
   case llvm::Triple::mipsel:
-    return createMips32ELTargetHandler(ctx);
+    return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx);
   case llvm::Triple::mips64el:
-    return createMips64ELTargetHandler(ctx);
+    return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx);
   default:
     llvm_unreachable("Unhandled arch");
   }

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,235 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp --------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsLinkingContext.h"
+#include "MipsSectionChunks.h"
+#include "MipsTargetLayout.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsReginfoSection<ELFT>::MipsReginfoSection(
+    const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
+    const MipsReginfo &reginfo)
+    : Section<ELFT>(ctx, ".reginfo", "MipsReginfo"),
+      _targetLayout(targetLayout) {
+  this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_REGINFO);
+  this->_entSize = sizeof(Elf_Mips_RegInfo);
+  this->_fsize = sizeof(Elf_Mips_RegInfo);
+  this->_msize = sizeof(Elf_Mips_RegInfo);
+  this->_alignment = 4;
+  this->_type = SHT_MIPS_REGINFO;
+  this->_flags = SHF_ALLOC;
+
+  std::memset(&_reginfo, 0, sizeof(_reginfo));
+  _reginfo.ri_gprmask = reginfo._gpRegMask;
+  _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
+  _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
+  _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
+  _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
+}
+
+template <class ELFT>
+void MipsReginfoSection<ELFT>::write(ELFWriter *writer,
+                                     TargetLayout<ELFT> &layout,
+                                     llvm::FileOutputBuffer &buffer) {
+  uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+  std::memcpy(dest, &_reginfo, this->_fsize);
+}
+
+template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
+  _reginfo.ri_gp_value = _targetLayout.getGPAddr();
+
+  if (this->_outputSection)
+    this->_outputSection->setType(this->_type);
+}
+
+template class MipsReginfoSection<ELF32LE>;
+template class MipsReginfoSection<ELF64LE>;
+
+template <class ELFT>
+MipsOptionsSection<ELFT>::MipsOptionsSection(
+    const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
+    const MipsReginfo &reginfo)
+    : Section<ELFT>(ctx, ".MIPS.options", "MipsOptions"),
+      _targetLayout(targetLayout) {
+  this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_OPTIONS);
+  this->_entSize = 1;
+  this->_alignment = 8;
+  this->_fsize = llvm::RoundUpToAlignment(
+      sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo), this->_alignment);
+  this->_msize = this->_fsize;
+  this->_type = SHT_MIPS_OPTIONS;
+  this->_flags = SHF_ALLOC | SHF_MIPS_NOSTRIP;
+
+  _header.kind = ODK_REGINFO;
+  _header.size = this->_fsize;
+  _header.section = 0;
+  _header.info = 0;
+
+  std::memset(&_reginfo, 0, sizeof(_reginfo));
+  _reginfo.ri_gprmask = reginfo._gpRegMask;
+  _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
+  _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
+  _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
+  _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
+}
+
+template <class ELFT>
+void MipsOptionsSection<ELFT>::write(ELFWriter *writer,
+                                     TargetLayout<ELFT> &layout,
+                                     llvm::FileOutputBuffer &buffer) {
+  uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+  std::memset(dest, 0, this->_fsize);
+  std::memcpy(dest, &_header, sizeof(_header));
+  std::memcpy(dest + sizeof(_header), &_reginfo, sizeof(_reginfo));
+}
+
+template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
+  _reginfo.ri_gp_value = _targetLayout.getGPAddr();
+
+  if (this->_outputSection)
+    this->_outputSection->setType(this->_type);
+}
+
+template class MipsOptionsSection<ELF32LE>;
+template class MipsOptionsSection<ELF64LE>;
+
+template <class ELFT>
+MipsGOTSection<ELFT>::MipsGOTSection(const MipsLinkingContext &ctx)
+    : AtomSection<ELFT>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_,
+                        MipsTargetLayout<ELFT>::ORDER_GOT),
+      _hasNonLocal(false), _localCount(0) {
+  this->_flags |= SHF_MIPS_GPREL;
+  this->_alignment = 4;
+}
+
+template <class ELFT>
+bool MipsGOTSection<ELFT>::compare(const Atom *a, const Atom *b) const {
+  auto ia = _posMap.find(a);
+  auto ib = _posMap.find(b);
+
+  if (ia != _posMap.end() && ib != _posMap.end())
+    return ia->second < ib->second;
+
+  return ia == _posMap.end() && ib != _posMap.end();
+}
+
+template <class ELFT>
+const AtomLayout *MipsGOTSection<ELFT>::appendAtom(const Atom *atom) {
+  const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
+
+  if (atom->name() == "_GLOBAL_OFFSET_TABLE_")
+    return AtomSection<ELFT>::appendAtom(atom);
+
+  for (const auto &r : *da) {
+    if (r->kindNamespace() != Reference::KindNamespace::ELF)
+      continue;
+    assert(r->kindArch() == Reference::KindArch::Mips);
+    switch (r->kindValue()) {
+    case LLD_R_MIPS_GLOBAL_GOT:
+      _hasNonLocal = true;
+      _posMap[r->target()] = _posMap.size();
+      return AtomSection<ELFT>::appendAtom(atom);
+    case R_MIPS_TLS_TPREL32:
+    case R_MIPS_TLS_DTPREL32:
+    case R_MIPS_TLS_TPREL64:
+    case R_MIPS_TLS_DTPREL64:
+      _hasNonLocal = true;
+      _tlsMap[r->target()] = _tlsMap.size();
+      return AtomSection<ELFT>::appendAtom(atom);
+    case R_MIPS_TLS_DTPMOD32:
+    case R_MIPS_TLS_DTPMOD64:
+      _hasNonLocal = true;
+      break;
+    }
+  }
+
+  if (!_hasNonLocal)
+    ++_localCount;
+
+  return AtomSection<ELFT>::appendAtom(atom);
+}
+
+template class MipsGOTSection<ELF32LE>;
+template class MipsGOTSection<ELF64LE>;
+
+template <class ELFT>
+MipsPLTSection<ELFT>::MipsPLTSection(const MipsLinkingContext &ctx)
+    : AtomSection<ELFT>(ctx, ".plt", DefinedAtom::typeGOT, DefinedAtom::permR_X,
+                        MipsTargetLayout<ELFT>::ORDER_PLT) {}
+
+template <class ELFT>
+const AtomLayout *MipsPLTSection<ELFT>::findPLTLayout(const Atom *plt) const {
+  auto it = _pltLayoutMap.find(plt);
+  return it != _pltLayoutMap.end() ? it->second : nullptr;
+}
+
+template <class ELFT>
+const AtomLayout *MipsPLTSection<ELFT>::appendAtom(const Atom *atom) {
+  const auto *layout = AtomSection<ELFT>::appendAtom(atom);
+
+  const DefinedAtom *da = cast<DefinedAtom>(atom);
+
+  for (const auto &r : *da) {
+    if (r->kindNamespace() != Reference::KindNamespace::ELF)
+      continue;
+    assert(r->kindArch() == Reference::KindArch::Mips);
+    if (r->kindValue() == LLD_R_MIPS_STO_PLT) {
+      _pltLayoutMap[r->target()] = layout;
+      break;
+    }
+  }
+
+  return layout;
+}
+
+template class MipsPLTSection<ELF32LE>;
+template class MipsPLTSection<ELF64LE>;
+
+template <class ELFT> static bool isMips64EL() {
+  return ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+}
+
+template <class ELFT>
+MipsRelocationTable<ELFT>::MipsRelocationTable(const ELFLinkingContext &ctx,
+                                               StringRef str, int32_t order)
+    : RelocationTable<ELFT>(ctx, str, order) {}
+
+template <class ELFT>
+void MipsRelocationTable<ELFT>::writeRela(ELFWriter *writer, Elf_Rela &r,
+                                          const DefinedAtom &atom,
+                                          const Reference &ref) {
+  uint32_t rType = ref.kindValue() | (ref.tag() << 8);
+  r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType,
+                     isMips64EL<ELFT>());
+  r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+  // The addend is used only by relative relocations
+  if (this->_ctx.isRelativeReloc(ref))
+    r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
+  else
+    r.r_addend = 0;
+}
+
+template <class ELFT>
+void MipsRelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r,
+                                         const DefinedAtom &atom,
+                                         const Reference &ref) {
+  uint32_t rType = ref.kindValue() | (ref.tag() << 8);
+  r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType,
+                     isMips64EL<ELFT>());
+  r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+}
+
+template class MipsRelocationTable<ELF32LE>;
+template class MipsRelocationTable<ELF64LE>;
+
+} // elf
+} // lld

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=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Wed May 27 06:56:15 2015
@@ -23,41 +23,14 @@ template <class ELFT> class MipsReginfoS
 public:
   MipsReginfoSection(const ELFLinkingContext &ctx,
                      MipsTargetLayout<ELFT> &targetLayout,
-                     const MipsReginfo &reginfo)
-      : Section<ELFT>(ctx, ".reginfo", "MipsReginfo"),
-        _targetLayout(targetLayout) {
-    this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_REGINFO);
-    this->_entSize = sizeof(Elf_Mips_RegInfo);
-    this->_fsize = sizeof(Elf_Mips_RegInfo);
-    this->_msize = sizeof(Elf_Mips_RegInfo);
-    this->_alignment = 4;
-    this->_type = SHT_MIPS_REGINFO;
-    this->_flags = SHF_ALLOC;
-
-    std::memset(&_reginfo, 0, sizeof(_reginfo));
-    _reginfo.ri_gprmask = reginfo._gpRegMask;
-    _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
-    _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
-    _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
-    _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
-  }
+                     const MipsReginfo &reginfo);
 
   StringRef segmentKindToStr() const override { return "REGINFO"; }
-
   bool hasOutputSegment() const override { return true; }
 
   void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
-             llvm::FileOutputBuffer &buffer) override {
-    uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
-    std::memcpy(dest, &_reginfo, this->_fsize);
-  }
-
-  void finalize() override {
-    _reginfo.ri_gp_value = _targetLayout.getGPAddr();
-
-    if (this->_outputSection)
-      this->_outputSection->setType(this->_type);
-  }
+             llvm::FileOutputBuffer &buffer) override;
+  void finalize() override;
 
 private:
   typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
@@ -69,51 +42,15 @@ private:
 /// \brief Handle .MIPS.options section
 template <class ELFT> class MipsOptionsSection : public Section<ELFT> {
 public:
-  typedef typename std::vector<MipsReginfo>::const_iterator mask_const_iterator;
-
   MipsOptionsSection(const ELFLinkingContext &ctx,
                      MipsTargetLayout<ELFT> &targetLayout,
-                     const MipsReginfo &reginfo)
-      : Section<ELFT>(ctx, ".MIPS.options", "MipsOptions"),
-        _targetLayout(targetLayout) {
-    this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_OPTIONS);
-    this->_entSize = 1;
-    this->_alignment = 8;
-    this->_fsize = llvm::RoundUpToAlignment(
-        sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo), this->_alignment);
-    this->_msize = this->_fsize;
-    this->_type = SHT_MIPS_OPTIONS;
-    this->_flags = SHF_ALLOC | SHF_MIPS_NOSTRIP;
-
-    _header.kind = ODK_REGINFO;
-    _header.size = this->_fsize;
-    _header.section = 0;
-    _header.info = 0;
-
-    std::memset(&_reginfo, 0, sizeof(_reginfo));
-    _reginfo.ri_gprmask = reginfo._gpRegMask;
-    _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
-    _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
-    _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
-    _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
-  }
+                     const MipsReginfo &reginfo);
 
   bool hasOutputSegment() const override { return true; }
 
   void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
-             llvm::FileOutputBuffer &buffer) override {
-    uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
-    std::memset(dest, 0, this->_fsize);
-    std::memcpy(dest, &_header, sizeof(_header));
-    std::memcpy(dest + sizeof(_header), &_reginfo, sizeof(_reginfo));
-  }
-
-  void finalize() override {
-    _reginfo.ri_gp_value = _targetLayout.getGPAddr();
-
-    if (this->_outputSection)
-      this->_outputSection->setType(this->_type);
-  }
+             llvm::FileOutputBuffer &buffer) override;
+  void finalize() override;
 
 private:
   typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
@@ -127,14 +64,7 @@ private:
 /// \brief Handle Mips GOT section
 template <class ELFT> class MipsGOTSection : public AtomSection<ELFT> {
 public:
-  MipsGOTSection(const MipsLinkingContext &ctx)
-      : AtomSection<ELFT>(ctx, ".got", DefinedAtom::typeGOT,
-                          DefinedAtom::permRW_,
-                          MipsTargetLayout<ELFT>::ORDER_GOT),
-        _hasNonLocal(false), _localCount(0) {
-    this->_flags |= SHF_MIPS_GPREL;
-    this->_alignment = 4;
-  }
+  MipsGOTSection(const MipsLinkingContext &ctx);
 
   /// \brief Number of local GOT entries.
   std::size_t getLocalCount() const { return _localCount; }
@@ -148,50 +78,9 @@ public:
   }
 
   /// \brief Compare two atoms accordingly theirs positions in the GOT.
-  bool compare(const Atom *a, const Atom *b) const {
-    auto ia = _posMap.find(a);
-    auto ib = _posMap.find(b);
-
-    if (ia != _posMap.end() && ib != _posMap.end())
-      return ia->second < ib->second;
+  bool compare(const Atom *a, const Atom *b) const;
 
-    return ia == _posMap.end() && ib != _posMap.end();
-  }
-
-  const AtomLayout *appendAtom(const Atom *atom) override {
-    const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
-
-    if (atom->name() == "_GLOBAL_OFFSET_TABLE_")
-      return AtomSection<ELFT>::appendAtom(atom);
-
-    for (const auto &r : *da) {
-      if (r->kindNamespace() != Reference::KindNamespace::ELF)
-        continue;
-      assert(r->kindArch() == Reference::KindArch::Mips);
-      switch (r->kindValue()) {
-      case LLD_R_MIPS_GLOBAL_GOT:
-        _hasNonLocal = true;
-        _posMap[r->target()] = _posMap.size();
-        return AtomSection<ELFT>::appendAtom(atom);
-      case R_MIPS_TLS_TPREL32:
-      case R_MIPS_TLS_DTPREL32:
-      case R_MIPS_TLS_TPREL64:
-      case R_MIPS_TLS_DTPREL64:
-        _hasNonLocal = true;
-        _tlsMap[r->target()] = _tlsMap.size();
-        return AtomSection<ELFT>::appendAtom(atom);
-      case R_MIPS_TLS_DTPMOD32:
-      case R_MIPS_TLS_DTPMOD64:
-        _hasNonLocal = true;
-        break;
-      }
-    }
-
-    if (!_hasNonLocal)
-      ++_localCount;
-
-    return AtomSection<ELFT>::appendAtom(atom);
-  }
+  const AtomLayout *appendAtom(const Atom *atom) override;
 
 private:
   /// \brief True if the GOT contains non-local entries.
@@ -210,33 +99,11 @@ private:
 /// \brief Handle Mips PLT section
 template <class ELFT> class MipsPLTSection : public AtomSection<ELFT> {
 public:
-  MipsPLTSection(const MipsLinkingContext &ctx)
-      : AtomSection<ELFT>(ctx, ".plt", DefinedAtom::typeGOT,
-                          DefinedAtom::permR_X,
-                          MipsTargetLayout<ELFT>::ORDER_PLT) {}
-
-  const AtomLayout *findPLTLayout(const Atom *plt) const {
-    auto it = _pltLayoutMap.find(plt);
-    return it != _pltLayoutMap.end() ? it->second : nullptr;
-  }
+  MipsPLTSection(const MipsLinkingContext &ctx);
 
-  const AtomLayout *appendAtom(const Atom *atom) override {
-    const auto *layout = AtomSection<ELFT>::appendAtom(atom);
+  const AtomLayout *findPLTLayout(const Atom *plt) const;
 
-    const DefinedAtom *da = cast<DefinedAtom>(atom);
-
-    for (const auto &r : *da) {
-      if (r->kindNamespace() != Reference::KindNamespace::ELF)
-        continue;
-      assert(r->kindArch() == Reference::KindArch::Mips);
-      if (r->kindValue() == LLD_R_MIPS_STO_PLT) {
-        _pltLayoutMap[r->target()] = layout;
-        break;
-      }
-    }
-
-    return layout;
-  }
+  const AtomLayout *appendAtom(const Atom *atom) override;
 
 private:
   /// \brief Map PLT Atoms to their layouts.
@@ -247,33 +114,15 @@ template <class ELFT> class MipsRelocati
   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:
   MipsRelocationTable(const ELFLinkingContext &ctx, StringRef str,
-                      int32_t order)
-      : RelocationTable<ELFT>(ctx, str, order) {}
+                      int32_t order);
 
 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->_ctx.isRelativeReloc(ref))
-      r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
-    else
-      r.r_addend = 0;
-  }
-
+                 const Reference &ref) override;
   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();
-  }
+                const Reference &ref) override;
 };
 
 } // elf

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,155 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp ----------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ELFReader.h"
+#include "MipsELFFile.h"
+#include "MipsELFWriters.h"
+#include "MipsTargetHandler.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsTargetHandler<ELFT>::MipsTargetHandler(MipsLinkingContext &ctx)
+    : _ctx(ctx), _targetLayout(new MipsTargetLayout<ELFT>(ctx)),
+      _relocationHandler(
+          createMipsRelocationHandler<ELFT>(ctx, *_targetLayout)) {}
+
+template <class ELFT>
+std::unique_ptr<Reader> MipsTargetHandler<ELFT>::getObjReader() {
+  return llvm::make_unique<ELFReader<MipsELFFile<ELFT>>>(_ctx);
+}
+
+template <class ELFT>
+std::unique_ptr<Reader> MipsTargetHandler<ELFT>::getDSOReader() {
+  return llvm::make_unique<ELFReader<DynamicFile<ELFT>>>(_ctx);
+}
+
+template <class ELFT>
+const TargetRelocationHandler &
+MipsTargetHandler<ELFT>::getRelocationHandler() const {
+  return *_relocationHandler;
+}
+
+template <class ELFT>
+std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() {
+  switch (_ctx.getOutputELFType()) {
+  case llvm::ELF::ET_EXEC:
+    return llvm::make_unique<MipsExecutableWriter<ELFT>>(_ctx, *_targetLayout);
+  case llvm::ELF::ET_DYN:
+    return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>(_ctx,
+                                                             *_targetLayout);
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
+  }
+}
+
+template class MipsTargetHandler<ELF32LE>;
+template class MipsTargetHandler<ELF64LE>;
+
+template <class ELFT>
+MipsSymbolTable<ELFT>::MipsSymbolTable(const ELFLinkingContext &ctx)
+    : SymbolTable<ELFT>(ctx, ".symtab",
+                        TargetLayout<ELFT>::ORDER_SYMBOL_TABLE) {}
+
+template <class ELFT>
+void MipsSymbolTable<ELFT>::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
+                                           int64_t addr) {
+  SymbolTable<ELFT>::addDefinedAtom(sym, da, addr);
+
+  switch (da->codeModel()) {
+  case DefinedAtom::codeMipsMicro:
+    sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS;
+    break;
+  case DefinedAtom::codeMipsMicroPIC:
+    sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC;
+    break;
+  default:
+    break;
+  }
+}
+
+template <class ELFT> void MipsSymbolTable<ELFT>::finalize(bool sort) {
+  SymbolTable<ELFT>::finalize(sort);
+
+  for (auto &ste : this->_symbolTable) {
+    if (!ste._atom)
+      continue;
+    if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
+      if (da->codeModel() == DefinedAtom::codeMipsMicro ||
+          da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
+        // Adjust dynamic microMIPS symbol value. That allows a dynamic
+        // linker to recognize and handle this symbol correctly.
+        ste._symbol.st_value = ste._symbol.st_value | 1;
+      }
+    }
+  }
+}
+
+template class MipsSymbolTable<ELF32LE>;
+template class MipsSymbolTable<ELF64LE>;
+
+template <class ELFT>
+MipsDynamicSymbolTable<ELFT>::MipsDynamicSymbolTable(
+    const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
+    : DynamicSymbolTable<ELFT>(ctx, layout, ".dynsym",
+                               TargetLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS),
+      _targetLayout(layout) {}
+
+template <class ELFT> void MipsDynamicSymbolTable<ELFT>::sortSymbols() {
+  typedef typename DynamicSymbolTable<ELFT>::SymbolEntry SymbolEntry;
+  std::stable_sort(this->_symbolTable.begin(), this->_symbolTable.end(),
+                   [this](const SymbolEntry &A, const SymbolEntry &B) {
+                     if (A._symbol.getBinding() != STB_GLOBAL &&
+                         B._symbol.getBinding() != STB_GLOBAL)
+                       return A._symbol.getBinding() < B._symbol.getBinding();
+
+                     return _targetLayout.getGOTSection().compare(A._atom,
+                                                                  B._atom);
+                   });
+}
+
+template <class ELFT> void MipsDynamicSymbolTable<ELFT>::finalize() {
+  DynamicSymbolTable<ELFT>::finalize();
+
+  const auto &pltSection = _targetLayout.getPLTSection();
+
+  for (auto &ste : this->_symbolTable) {
+    const Atom *a = ste._atom;
+    if (!a)
+      continue;
+    if (auto *layout = pltSection.findPLTLayout(a)) {
+      a = layout->_atom;
+      // Under some conditions a dynamic symbol table record should hold
+      // a symbol value of the corresponding PLT entry. For details look
+      // at the PLT entry creation code in the class MipsRelocationPass.
+      // Let's update atomLayout fields for such symbols.
+      assert(!ste._atomLayout);
+      ste._symbol.st_value = layout->_virtualAddr;
+      ste._symbol.st_other |= ELF::STO_MIPS_PLT;
+    }
+
+    if (const auto *da = dyn_cast<DefinedAtom>(a)) {
+      if (da->codeModel() == DefinedAtom::codeMipsMicro ||
+          da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
+        // Adjust dynamic microMIPS symbol value. That allows a dynamic
+        // linker to recognize and handle this symbol correctly.
+        ste._symbol.st_value = ste._symbol.st_value | 1;
+      }
+    }
+  }
+}
+
+template class MipsDynamicSymbolTable<ELF32LE>;
+template class MipsDynamicSymbolTable<ELF64LE>;
+
+}
+}

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=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Wed May 27 06:56:15 2015
@@ -9,10 +9,6 @@
 #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
 #define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
 
-#include "ELFReader.h"
-#include "MipsDynamicLibraryWriter.h"
-#include "MipsELFFile.h"
-#include "MipsExecutableWriter.h"
 #include "MipsLinkingContext.h"
 #include "MipsTargetLayout.h"
 #include "TargetHandler.h"
@@ -23,37 +19,12 @@ namespace elf {
 /// \brief TargetHandler for Mips
 template <class ELFT> class MipsTargetHandler final : public TargetHandler {
 public:
-  MipsTargetHandler(MipsLinkingContext &ctx)
-      : _ctx(ctx), _targetLayout(new MipsTargetLayout<ELFT>(ctx)),
-        _relocationHandler(
-            createMipsRelocationHandler<ELFT>(ctx, *_targetLayout)) {}
-
-  std::unique_ptr<Reader> getObjReader() override {
-    return llvm::make_unique<ELFReader<MipsELFFile<ELFT>>>(_ctx);
-  }
-
-  std::unique_ptr<Reader> getDSOReader() override {
-    return llvm::make_unique<ELFReader<DynamicFile<ELFT>>>(_ctx);
-  }
-
-  const TargetRelocationHandler &getRelocationHandler() const override {
-    return *_relocationHandler;
-  }
-
-  std::unique_ptr<Writer> getWriter() override {
-    switch (_ctx.getOutputELFType()) {
-    case llvm::ELF::ET_EXEC:
-      return llvm::make_unique<MipsExecutableWriter<ELFT>>(
-          _ctx, *_targetLayout);
-    case llvm::ELF::ET_DYN:
-      return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>(
-          _ctx, *_targetLayout);
-    case llvm::ELF::ET_REL:
-      llvm_unreachable("TODO: support -r mode");
-    default:
-      llvm_unreachable("unsupported output type");
-    }
-  }
+  MipsTargetHandler(MipsLinkingContext &ctx);
+
+  std::unique_ptr<Reader> getObjReader() override;
+  std::unique_ptr<Reader> getDSOReader() override;
+  const TargetRelocationHandler &getRelocationHandler() const override;
+  std::unique_ptr<Writer> getWriter() override;
 
 private:
   MipsLinkingContext &_ctx;
@@ -65,105 +36,26 @@ template <class ELFT> class MipsSymbolTa
 public:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
 
-  MipsSymbolTable(const ELFLinkingContext &ctx)
-      : SymbolTable<ELFT>(ctx, ".symtab",
-                          TargetLayout<ELFT>::ORDER_SYMBOL_TABLE) {}
+  MipsSymbolTable(const ELFLinkingContext &ctx);
 
   void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
-                      int64_t addr) override {
-    SymbolTable<ELFT>::addDefinedAtom(sym, da, addr);
-
-    switch (da->codeModel()) {
-    case DefinedAtom::codeMipsMicro:
-      sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS;
-      break;
-    case DefinedAtom::codeMipsMicroPIC:
-      sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC;
-      break;
-    default:
-      break;
-    }
-  }
-
-  void finalize(bool sort) override {
-    SymbolTable<ELFT>::finalize(sort);
-
-    for (auto &ste : this->_symbolTable) {
-      if (!ste._atom)
-        continue;
-      if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
-        if (da->codeModel() == DefinedAtom::codeMipsMicro ||
-            da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
-          // Adjust dynamic microMIPS symbol value. That allows a dynamic
-          // linker to recognize and handle this symbol correctly.
-          ste._symbol.st_value = ste._symbol.st_value | 1;
-        }
-      }
-    }
-  }
+                      int64_t addr) override;
+  void finalize(bool sort) override;
 };
 
 template <class ELFT>
 class MipsDynamicSymbolTable : public DynamicSymbolTable<ELFT> {
 public:
   MipsDynamicSymbolTable(const ELFLinkingContext &ctx,
-                         MipsTargetLayout<ELFT> &layout)
-      : DynamicSymbolTable<ELFT>(ctx, layout, ".dynsym",
-                                 TargetLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS),
-        _targetLayout(layout) {}
-
-  void sortSymbols() override {
-    typedef typename DynamicSymbolTable<ELFT>::SymbolEntry SymbolEntry;
-    std::stable_sort(this->_symbolTable.begin(), this->_symbolTable.end(),
-                     [this](const SymbolEntry &A, const SymbolEntry &B) {
-      if (A._symbol.getBinding() != STB_GLOBAL &&
-          B._symbol.getBinding() != STB_GLOBAL)
-        return A._symbol.getBinding() < B._symbol.getBinding();
-
-      return _targetLayout.getGOTSection().compare(A._atom, B._atom);
-    });
-  }
-
-  void finalize() override {
-    DynamicSymbolTable<ELFT>::finalize();
-
-    const auto &pltSection = _targetLayout.getPLTSection();
-
-    for (auto &ste : this->_symbolTable) {
-      const Atom *a = ste._atom;
-      if (!a)
-        continue;
-      if (auto *layout = pltSection.findPLTLayout(a)) {
-        a = layout->_atom;
-        // Under some conditions a dynamic symbol table record should hold
-        // a symbol value of the corresponding PLT entry. For details look
-        // at the PLT entry creation code in the class MipsRelocationPass.
-        // Let's update atomLayout fields for such symbols.
-        assert(!ste._atomLayout);
-        ste._symbol.st_value = layout->_virtualAddr;
-        ste._symbol.st_other |= ELF::STO_MIPS_PLT;
-      }
-
-      if (const auto *da = dyn_cast<DefinedAtom>(a)) {
-        if (da->codeModel() == DefinedAtom::codeMipsMicro ||
-            da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
-          // Adjust dynamic microMIPS symbol value. That allows a dynamic
-          // linker to recognize and handle this symbol correctly.
-          ste._symbol.st_value = ste._symbol.st_value | 1;
-        }
-      }
-    }
-  }
+                         MipsTargetLayout<ELFT> &layout);
+
+  void sortSymbols() override;
+  void finalize() override;
 
 private:
   MipsTargetLayout<ELFT> &_targetLayout;
 };
 
-std::unique_ptr<TargetHandler>
-createMips32ELTargetHandler(MipsLinkingContext &ctx);
-std::unique_ptr<TargetHandler>
-createMips64ELTargetHandler(MipsLinkingContext &ctx);
-
 } // end namespace elf
 } // end namespace lld
 

Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp (removed)
@@ -1,18 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp ----------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsTargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<TargetHandler>
-lld::elf::createMips32ELTargetHandler(MipsLinkingContext &ctx) {
-  return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx);
-}

Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp (removed)
@@ -1,18 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp ----------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsTargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<TargetHandler>
-lld::elf::createMips64ELTargetHandler(MipsLinkingContext &ctx) {
-  return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx);
-}

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,83 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp ---------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsLinkingContext.h"
+#include "MipsTargetLayout.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsTargetLayout<ELFT>::MipsTargetLayout(MipsLinkingContext &ctx)
+    : TargetLayout<ELFT>(ctx),
+      _gotSection(new (this->_allocator) MipsGOTSection<ELFT>(ctx)),
+      _pltSection(new (this->_allocator) MipsPLTSection<ELFT>(ctx)) {}
+
+template <class ELFT>
+AtomSection<ELFT> *MipsTargetLayout<ELFT>::createSection(
+    StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions,
+    typename TargetLayout<ELFT>::SectionOrder order) {
+  if (type == DefinedAtom::typeGOT && name == ".got")
+    return _gotSection;
+  if (type == DefinedAtom::typeStub && name == ".plt")
+    return _pltSection;
+  return TargetLayout<ELFT>::createSection(name, type, permissions, order);
+}
+
+template <class ELFT>
+typename TargetLayout<ELFT>::SegmentType
+MipsTargetLayout<ELFT>::getSegmentType(Section<ELFT> *section) const {
+  switch (section->order()) {
+  case ORDER_MIPS_REGINFO:
+    return llvm::ELF::PT_MIPS_REGINFO;
+  case ORDER_MIPS_OPTIONS:
+    return llvm::ELF::PT_LOAD;
+  default:
+    return TargetLayout<ELFT>::getSegmentType(section);
+  }
+}
+
+template <class ELFT> uint64_t MipsTargetLayout<ELFT>::getGPAddr() {
+  std::call_once(_gpOnce, [this]() {
+    if (AtomLayout *a = this->findAbsoluteAtom("_gp"))
+      _gpAddr = a->_virtualAddr;
+  });
+  return _gpAddr;
+}
+
+template <class ELFT>
+typename TargetLayout<ELFT>::SectionOrder
+MipsTargetLayout<ELFT>::getSectionOrder(StringRef name, int32_t contentType,
+                                        int32_t contentPermissions) {
+  if ((contentType == DefinedAtom::typeStub) && (name.startswith(".text")))
+    return TargetLayout<ELFT>::ORDER_TEXT;
+
+  return TargetLayout<ELFT>::getSectionOrder(name, contentType,
+                                             contentPermissions);
+}
+
+template <class ELFT>
+unique_bump_ptr<RelocationTable<ELFT>>
+MipsTargetLayout<ELFT>::createRelocationTable(StringRef name, int32_t order) {
+  return unique_bump_ptr<RelocationTable<ELFT>>(new (
+      this->_allocator) MipsRelocationTable<ELFT>(this->_ctx, name, order));
+}
+
+template <class ELFT>
+uint64_t MipsTargetLayout<ELFT>::getLookupSectionFlags(
+    const OutputSection<ELFT> *os) const {
+  uint64_t flags = TargetLayout<ELFT>::getLookupSectionFlags(os);
+  return flags & ~llvm::ELF::SHF_MIPS_NOSTRIP;
+}
+
+template class MipsTargetLayout<ELF32LE>;
+template class MipsTargetLayout<ELF64LE>;
+
+} // end namespace elf
+} // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h Wed May 27 06:56:15 2015
@@ -25,10 +25,7 @@ public:
     ORDER_MIPS_OPTIONS
   };
 
-  MipsTargetLayout(MipsLinkingContext &ctx)
-      : TargetLayout<ELFT>(ctx),
-        _gotSection(new (this->_allocator) MipsGOTSection<ELFT>(ctx)),
-        _pltSection(new (this->_allocator) MipsPLTSection<ELFT>(ctx)) {}
+  MipsTargetLayout(MipsLinkingContext &ctx);
 
   const MipsGOTSection<ELFT> &getGOTSection() const { return *_gotSection; }
   const MipsPLTSection<ELFT> &getPLTSection() const { return *_pltSection; }
@@ -36,60 +33,26 @@ public:
   AtomSection<ELFT> *
   createSection(StringRef name, int32_t type,
                 DefinedAtom::ContentPermissions permissions,
-                typename TargetLayout<ELFT>::SectionOrder order) override {
-    if (type == DefinedAtom::typeGOT && name == ".got")
-      return _gotSection;
-    if (type == DefinedAtom::typeStub && name == ".plt")
-      return _pltSection;
-    return TargetLayout<ELFT>::createSection(name, type, permissions, order);
-  }
+                typename TargetLayout<ELFT>::SectionOrder order) override;
 
   typename TargetLayout<ELFT>::SegmentType
-  getSegmentType(Section<ELFT> *section) const override {
-    switch (section->order()) {
-    case ORDER_MIPS_REGINFO:
-      return llvm::ELF::PT_MIPS_REGINFO;
-    case ORDER_MIPS_OPTIONS:
-      return llvm::ELF::PT_LOAD;
-    default:
-      return TargetLayout<ELFT>::getSegmentType(section);
-    }
-  }
+  getSegmentType(Section<ELFT> *section) const override;
 
   /// \brief GP offset relative to .got section.
   uint64_t getGPOffset() const { return 0x7FF0; }
 
   /// \brief Get '_gp' symbol address.
-  uint64_t getGPAddr() {
-    std::call_once(_gpOnce, [this]() {
-      if (AtomLayout *a = this->findAbsoluteAtom("_gp"))
-        _gpAddr = a->_virtualAddr;
-    });
-    return _gpAddr;
-  }
+  uint64_t getGPAddr();
 
   /// \brief Return the section order for a input section
   typename TargetLayout<ELFT>::SectionOrder
   getSectionOrder(StringRef name, int32_t contentType,
-                  int32_t contentPermissions) override {
-    if ((contentType == DefinedAtom::typeStub) && (name.startswith(".text")))
-      return TargetLayout<ELFT>::ORDER_TEXT;
-
-    return TargetLayout<ELFT>::getSectionOrder(name, contentType,
-                                               contentPermissions);
-  }
+                  int32_t contentPermissions) override;
 
 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->_ctx, name, order));
-  }
-
-  uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const override {
-    uint64_t flags = TargetLayout<ELFT>::getLookupSectionFlags(os);
-    return flags & ~llvm::ELF::SHF_MIPS_NOSTRIP;
-  }
+  createRelocationTable(StringRef name, int32_t order) override;
+  uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const override;
 
 private:
   MipsGOTSection<ELFT> *_gotSection;





More information about the llvm-commits mailing list