[lld] r200177 - [ELF] Make changes to all the targets supported currently

Shankar Easwaran shankare at codeaurora.org
Sun Jan 26 17:21:03 PST 2014


Author: shankare
Date: Sun Jan 26 19:21:02 2014
New Revision: 200177

URL: http://llvm.org/viewvc/llvm-project?rev=200177&view=rev
Log:
[ELF] Make changes to all the targets supported currently

X86_64,X86,PPC,Hexagon,Mips

No change in functionality.

Added:
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Chunk.h
    lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
    lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
    lld/trunk/test/elf/Hexagon/dynlib-syms.test

Modified: lld/trunk/lib/ReaderWriter/ELF/Chunk.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Sun Jan 26 19:21:02 2014
@@ -27,6 +27,8 @@ class ELFLinkingContext;
 namespace elf {
 class ELFWriter;
 
+template <class ELFT> class TargetLayout;
+
 /// \brief A chunk is a contiguous region of space
 template<class ELFT>
 class Chunk {
@@ -73,7 +75,8 @@ public:
   // Whats the contentType of the chunk ?
   virtual int getContentType() const = 0;
   // Writer the chunk
-  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0;
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                     llvm::FileOutputBuffer &buffer) = 0;
   // Finalize the chunk before assigning offsets/virtual addresses
   virtual void doPreFlight() = 0;
   // Finalize the chunk before writing

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -29,49 +29,10 @@ public:
   DefaultTargetHandler(ELFLinkingContext &context)
       : TargetHandler<ELFT>(context) {}
 
-  bool doesOverrideELFHeader() { return false; }
-
-  void setELFHeader(ELFHeader<ELFT> *elfHeader) {
-    llvm_unreachable("Target should provide implementation for function ");
-  }
-
   const TargetRelocationHandler<ELFT> &getRelocationHandler() const {
     llvm_unreachable("Target should provide implementation for function ");
   }
 
-  /// Create a set of Default target sections that a target might needj
-  void createDefaultSections() {}
-
-  /// \brief Add a section to the current Layout
-  void addSection(Section<ELFT> *section) {}
-
-  /// \brief add new symbol file
-  bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) {
-    return true;
-  }
-
-  /// \brief Finalize the symbol values
-  void finalizeSymbolValues() {}
-
-  /// \brief allocate Commons, some architectures may move small common
-  /// symbols over to small data, this would also be used
-  void allocateCommons() {}
-
-  /// \brief create dynamic table
-  LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() {
-    return LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)(
-        new (_alloc) DynamicTable<ELFT>(
-            this->_context, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
-  }
-
-  /// \brief create dynamic symbol table
-  LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable() {
-    return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)(
-        new (_alloc) DynamicSymbolTable<ELFT>(
-            this->_context, ".dynsym",
-            DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
-  }
-
   virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
     return std::unique_ptr<Reader>(new ELFObjectReader(atomizeStrings));
   }
@@ -80,64 +41,9 @@ public:
     return std::unique_ptr<Reader>(new ELFDSOReader(useShlibUndefines));
   }
 
-  virtual std::unique_ptr<Writer> getWriter();
-
-protected:
-  llvm::BumpPtrAllocator _alloc;
+  virtual std::unique_ptr<Writer> getWriter() = 0;
 };
 
-template <class ELFT>
-std::unique_ptr<Writer> DefaultTargetHandler<ELFT>::getWriter() {
-  switch (this->_context.getOutputELFType()) {
-  case llvm::ELF::ET_EXEC:
-    if (this->_context.is64Bits()) {
-      if (this->_context.isLittleEndian())
-        return std::unique_ptr<Writer>(
-            new elf::ExecutableWriter<ELFType<support::little, 8, true>>(
-                this->_context));
-      else
-        return std::unique_ptr<Writer>(
-            new elf::ExecutableWriter<ELFType<support::big, 8, true>>(
-                this->_context));
-    } else {
-      if (this->_context.isLittleEndian())
-        return std::unique_ptr<Writer>(
-            new elf::ExecutableWriter<ELFType<support::little, 4, false>>(
-                this->_context));
-      else
-        return std::unique_ptr<Writer>(
-            new elf::ExecutableWriter<ELFType<support::big, 4, false>>(
-                this->_context));
-    }
-    break;
-  case llvm::ELF::ET_DYN:
-    if (this->_context.is64Bits()) {
-      if (this->_context.isLittleEndian())
-        return std::unique_ptr<Writer>(
-            new elf::DynamicLibraryWriter<ELFType<support::little, 8, true>>(
-                this->_context));
-      else
-        return std::unique_ptr<Writer>(
-            new elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(
-                this->_context));
-    } else {
-      if (this->_context.isLittleEndian())
-        return std::unique_ptr<Writer>(
-            new elf::DynamicLibraryWriter<ELFType<support::little, 4, false>>(
-                this->_context));
-      else
-        return std::unique_ptr<Writer>(
-            new elf::DynamicLibraryWriter<ELFType<support::big, 4, false>>(
-                this->_context));
-    }
-    break;
-  case llvm::ELF::ET_REL:
-    llvm_unreachable("TODO: support -r mode");
-  default:
-    llvm_unreachable("unsupported output type");
-  }
-}
-
 } // end namespace elf
 } // end namespace lld
 #endif

Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -25,17 +25,18 @@ class DynamicLibraryWriter;
 template<class ELFT>
 class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
 public:
-  DynamicLibraryWriter(const ELFLinkingContext &context)
-      : OutputELFWriter<ELFT>(context),
+  DynamicLibraryWriter(const ELFLinkingContext &context,
+                       TargetLayout<ELFT> &layout)
+      : OutputELFWriter<ELFT>(context, layout),
         _runtimeFile(new CRuntimeFile<ELFT>(context)) {}
 
-private:
-  void buildDynamicSymbolTable(const File &file);
-  void addDefaultAtoms();
+protected:
+  virtual void buildDynamicSymbolTable(const File &file);
+  virtual void addDefaultAtoms();
   virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
-  void finalizeDefaultAtomValues();
+  virtual void finalizeDefaultAtomValues();
 
-  llvm::BumpPtrAllocator _alloc;
+protected:
   std::unique_ptr<CRuntimeFile<ELFT> > _runtimeFile;
 };
 
@@ -47,7 +48,7 @@ void DynamicLibraryWriter<ELFT>::buildDy
   // Add all the defined symbols to the dynamic symbol table
   // we need hooks into the Atom to find out which atoms need
   // to be exported
-  for (auto sec : this->_layout->sections())
+  for (auto sec : this->_layout.sections())
     if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
       for (const auto &atom : section->atoms()) {
         const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
@@ -71,7 +72,7 @@ template <class ELFT>
 bool DynamicLibraryWriter<ELFT>::createImplicitFiles(
     std::vector<std::unique_ptr<File> > &result) {
   // Add the default atoms as defined by executables
-  addDefaultAtoms();
+  DynamicLibraryWriter<ELFT>::addDefaultAtoms();
   OutputELFWriter<ELFT>::createImplicitFiles(result);
   result.push_back(std::move(_runtimeFile));
   return true;
@@ -79,17 +80,15 @@ bool DynamicLibraryWriter<ELFT>::createI
 
 template <class ELFT>
 void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
-  auto underScoreEndAtomIter = this->_layout->findAbsoluteAtom("_end");
+  auto underScoreEndAtomIter = this->_layout.findAbsoluteAtom("_end");
 
-  if (auto bssSection = this->_layout->findOutputSection(".bss")) {
+  if (auto bssSection = this->_layout.findOutputSection(".bss")) {
     (*underScoreEndAtomIter)->_virtualAddr =
         bssSection->virtualAddr() + bssSection->memSize();
-  } else if (auto dataSection = this->_layout->findOutputSection(".data")) {
+  } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
     (*underScoreEndAtomIter)->_virtualAddr =
         dataSection->virtualAddr() + dataSection->memSize();
   }
-
-  this->_targetHandler.finalizeSymbolValues();
 }
 
 } // namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -25,11 +25,11 @@ class ExecutableWriter;
 template<class ELFT>
 class ExecutableWriter : public OutputELFWriter<ELFT> {
 public:
-  ExecutableWriter(const ELFLinkingContext &context)
-      : OutputELFWriter<ELFT>(context),
+  ExecutableWriter(const ELFLinkingContext &context, TargetLayout<ELFT> &layout)
+      : OutputELFWriter<ELFT>(context, layout),
         _runtimeFile(new CRuntimeFile<ELFT>(context)) {}
 
-private:
+protected:
   virtual void addDefaultAtoms();
   virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
   virtual void finalizeDefaultAtomValues();
@@ -71,7 +71,7 @@ template <class ELFT>
 bool ExecutableWriter<ELFT>::createImplicitFiles(
     std::vector<std::unique_ptr<File> > &result) {
   // Add the default atoms as defined by executables
-  addDefaultAtoms();
+  ExecutableWriter<ELFT>::addDefaultAtoms();
   OutputELFWriter<ELFT>::createImplicitFiles(result);
   result.push_back(std::move(_runtimeFile));
   return true;
@@ -83,17 +83,17 @@ template <class ELFT> void ExecutableWri
     _interpSection.reset(new (this->_alloc) InterpSection<ELFT>(
         this->_context, ".interp", DefaultLayout<ELFT>::ORDER_INTERP,
         this->_context.getInterpreter()));
-    this->_layout->addSection(_interpSection.get());
+    this->_layout.addSection(_interpSection.get());
   }
 }
 
 /// Finalize the value of all the absolute symbols that we
 /// created
 template <class ELFT> void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
-  auto bssStartAtomIter = this->_layout->findAbsoluteAtom("__bss_start");
-  auto bssEndAtomIter = this->_layout->findAbsoluteAtom("__bss_end");
-  auto underScoreEndAtomIter = this->_layout->findAbsoluteAtom("_end");
-  auto endAtomIter = this->_layout->findAbsoluteAtom("end");
+  auto bssStartAtomIter = this->_layout.findAbsoluteAtom("__bss_start");
+  auto bssEndAtomIter = this->_layout.findAbsoluteAtom("__bss_end");
+  auto underScoreEndAtomIter = this->_layout.findAbsoluteAtom("_end");
+  auto endAtomIter = this->_layout.findAbsoluteAtom("end");
 
   auto startEnd = [&](StringRef sym, StringRef sec) -> void {
     // TODO: This looks like a good place to use Twine...
@@ -102,9 +102,9 @@ template <class ELFT> void ExecutableWri
     start += "_start";
     end += sym;
     end += "_end";
-    auto s = this->_layout->findAbsoluteAtom(start);
-    auto e = this->_layout->findAbsoluteAtom(end);
-    auto section = this->_layout->findOutputSection(sec);
+    auto s = this->_layout.findAbsoluteAtom(start);
+    auto e = this->_layout.findAbsoluteAtom(end);
+    auto section = this->_layout.findOutputSection(sec);
     if (section) {
       (*s)->_virtualAddr = section->virtualAddr();
       (*e)->_virtualAddr = section->virtualAddr() + section->memSize();
@@ -122,13 +122,13 @@ template <class ELFT> void ExecutableWri
     startEnd("rel_iplt", ".rel.plt");
   startEnd("fini_array", ".fini_array");
 
-  assert(!(bssStartAtomIter == this->_layout->absoluteAtoms().end() ||
-           bssEndAtomIter == this->_layout->absoluteAtoms().end() ||
-           underScoreEndAtomIter == this->_layout->absoluteAtoms().end() ||
-           endAtomIter == this->_layout->absoluteAtoms().end()) &&
+  assert(!(bssStartAtomIter == this->_layout.absoluteAtoms().end() ||
+           bssEndAtomIter == this->_layout.absoluteAtoms().end() ||
+           underScoreEndAtomIter == this->_layout.absoluteAtoms().end() ||
+           endAtomIter == this->_layout.absoluteAtoms().end()) &&
          "Unable to find the absolute atoms that have been added by lld");
 
-  auto bssSection = this->_layout->findOutputSection(".bss");
+  auto bssSection = this->_layout.findOutputSection(".bss");
 
   // If we don't find a bss section, then don't set these values
   if (bssSection) {
@@ -137,14 +137,11 @@ template <class ELFT> void ExecutableWri
         bssSection->virtualAddr() + bssSection->memSize();
     (*underScoreEndAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;
     (*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;
-  } else if (auto dataSection = this->_layout->findOutputSection(".data")) {
+  } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
     (*underScoreEndAtomIter)->_virtualAddr =
         dataSection->virtualAddr() + dataSection->memSize();
     (*endAtomIter)->_virtualAddr = (*underScoreEndAtomIter)->_virtualAddr;
   }
-
-  // Give a chance for the target to finalize its atom values
-  this->_targetHandler.finalizeSymbolValues();
 }
 
 } // namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h Sun Jan 26 19:21:02 2014
@@ -52,7 +52,8 @@ public:
 
   inline int getContentType() const { return Chunk<ELFT>::ContentType::Header; }
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+             llvm::FileOutputBuffer &buffer);
 
   virtual void doPreFlight() {}
 
@@ -78,7 +79,8 @@ ELFHeader<ELFT>::ELFHeader(const ELFLink
 }
 
 template <class ELFT>
-void ELFHeader<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+void ELFHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                            llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   uint8_t *atomContent = chunkBuffer + this->fileOffset();
   memcpy(atomContent, &_eh, fileSize());
@@ -132,7 +134,8 @@ public:
     return c->Kind() == Chunk<ELFT>::Kind::ProgramHeader;
   }
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+             llvm::FileOutputBuffer &buffer);
 
   /// \brief find a program header entry in the list of program headers
   ReversePhIterT
@@ -231,8 +234,8 @@ bool ProgramHeader<ELFT>::addSegment(Seg
 }
 
 template <class ELFT>
-void ProgramHeader<ELFT>::write(ELFWriter *writer,
-                                   llvm::FileOutputBuffer &buffer) {
+void ProgramHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                                llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   uint8_t *dest = chunkBuffer + this->fileOffset();
   for (auto phi : _ph) {
@@ -262,7 +265,8 @@ public:
     _stringSection = s;
   }
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+             llvm::FileOutputBuffer &buffer);
 
   virtual void doPreFlight() {}
 
@@ -336,15 +340,15 @@ SectionHeader<ELFT>::updateSection(Secti
 }
 
 template <class ELFT>
-void SectionHeader<ELFT>::write(ELFWriter *writer,
-                                   llvm::FileOutputBuffer &buffer) {
+void SectionHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                                llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   uint8_t *dest = chunkBuffer + this->fileOffset();
   for (auto shi : _sectionInfo) {
     memcpy(dest, shi, sizeof(Elf_Shdr));
     dest += sizeof(Elf_Shdr);
   }
-  _stringSection->write(writer, buffer);
+  _stringSection->write(writer, layout, buffer);
 }
 } // end namespace elf
 } // end namespace lld

Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,80 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
+//-------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_DYNAMIC_LIBRARY_WRITER_H
+#define HEXAGON_DYNAMIC_LIBRARY_WRITER_H
+
+#include "HexagonExecutableAtoms.h"
+#include "HexagonLinkingContext.h"
+#include "DynamicLibraryWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class HexagonTargetLayout;
+
+template <class ELFT>
+class HexagonDynamicLibraryWriter : public DynamicLibraryWriter<ELFT>,
+                                    public HexagonELFWriter<ELFT> {
+public:
+  HexagonDynamicLibraryWriter(HexagonLinkingContext &context,
+                              HexagonTargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+  virtual void finalizeDefaultAtomValues();
+
+  virtual error_code setELFHeader() {
+    DynamicLibraryWriter<ELFT>::setELFHeader();
+    HexagonELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+    return error_code::success();
+  }
+
+private:
+  void addDefaultAtoms() {
+    _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+    _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
+  }
+
+  HexagonLinkingContext &_hexagonLinkingContext;
+  HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+  std::unique_ptr<HexagonRuntimeFile<ELFT>> _hexagonRuntimeFile;
+};
+
+template <class ELFT>
+HexagonDynamicLibraryWriter<ELFT>::HexagonDynamicLibraryWriter(
+    HexagonLinkingContext &context, HexagonTargetLayout<ELFT> &layout)
+    : DynamicLibraryWriter<ELFT>(context, layout),
+      HexagonELFWriter<ELFT>(context, layout), _hexagonLinkingContext(context),
+      _hexagonTargetLayout(layout),
+      _hexagonRuntimeFile(new HexagonRuntimeFile<ELFT>(context)) {}
+
+template <class ELFT>
+bool HexagonDynamicLibraryWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+  // Add the default atoms as defined for hexagon
+  addDefaultAtoms();
+  result.push_back(std::move(_hexagonRuntimeFile));
+  return true;
+}
+
+template <class ELFT>
+void HexagonDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+  // Finalize the atom values that are part of the parent.
+  DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+  HexagonELFWriter<ELFT>::finalizeHexagonRuntimeAtomValues();
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // HEXAGON_DYNAMIC_LIBRARY_WRITER_H

Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,61 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h -------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HEXAGON_ELF_WRITERS_H
+#define HEXAGON_ELF_WRITERS_H
+
+#include "HexagonLinkingContext.h"
+#include "OutputELFWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class HexagonTargetLayout;
+
+template <typename ELFT> class HexagonELFWriter {
+public:
+  HexagonELFWriter(HexagonLinkingContext &context,
+                   HexagonTargetLayout<ELFT> &targetLayout)
+      : _hexagonLinkingContext(context), _hexagonTargetLayout(targetLayout) {}
+
+protected:
+  bool setELFHeader(ELFHeader<ELFT> &elfHeader) {
+    elfHeader.e_ident(llvm::ELF::EI_VERSION, 1);
+    elfHeader.e_ident(llvm::ELF::EI_OSABI, 0);
+    elfHeader.e_version(1);
+    elfHeader.e_flags(0x3);
+    return true;
+  }
+
+  void finalizeHexagonRuntimeAtomValues() {
+    if (_hexagonLinkingContext.isDynamic()) {
+      auto gotAtomIter =
+          _hexagonTargetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      auto gotpltSection = _hexagonTargetLayout.findOutputSection(".got.plt");
+      if (gotpltSection)
+        (*gotAtomIter)->_virtualAddr = gotpltSection->virtualAddr();
+      else
+        (*gotAtomIter)->_virtualAddr = 0;
+      auto dynamicAtomIter = _hexagonTargetLayout.findAbsoluteAtom("_DYNAMIC");
+      auto dynamicSection = _hexagonTargetLayout.findOutputSection(".dynamic");
+      if (dynamicSection)
+        (*dynamicAtomIter)->_virtualAddr = dynamicSection->virtualAddr();
+      else
+        (*dynamicAtomIter)->_virtualAddr = 0;
+    }
+  }
+
+private:
+  HexagonLinkingContext &_hexagonLinkingContext LLVM_ATTRIBUTE_UNUSED;
+  HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+};
+
+} // elf
+} // lld
+#endif // HEXAGON_ELF_WRITERS_H

Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,86 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h -------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_EXECUTABLE_WRITER_H
+#define HEXAGON_EXECUTABLE_WRITER_H
+
+#include "HexagonExecutableAtoms.h"
+#include "HexagonLinkingContext.h"
+#include "HexagonELFWriters.h"
+#include "ExecutableWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class HexagonTargetLayout;
+
+template <class ELFT>
+class HexagonExecutableWriter : public ExecutableWriter<ELFT>,
+                                public HexagonELFWriter<ELFT> {
+public:
+  HexagonExecutableWriter(HexagonLinkingContext &context,
+                          HexagonTargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+  virtual void finalizeDefaultAtomValues();
+
+  virtual error_code setELFHeader() {
+    ExecutableWriter<ELFT>::setELFHeader();
+    HexagonELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+    return error_code::success();
+  }
+
+private:
+  void addDefaultAtoms() {
+    _hexagonRuntimeFile->addAbsoluteAtom("_SDA_BASE_");
+    if (this->_context.isDynamic()) {
+      _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
+    }
+  }
+
+  HexagonLinkingContext &_hexagonLinkingContext;
+  HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+  std::unique_ptr<HexagonRuntimeFile<ELFT>> _hexagonRuntimeFile;
+};
+
+template <class ELFT>
+HexagonExecutableWriter<ELFT>::HexagonExecutableWriter(
+    HexagonLinkingContext &context, HexagonTargetLayout<ELFT> &layout)
+    : ExecutableWriter<ELFT>(context, layout),
+      HexagonELFWriter<ELFT>(context, layout), _hexagonLinkingContext(context),
+      _hexagonTargetLayout(layout),
+      _hexagonRuntimeFile(new HexagonRuntimeFile<ELFT>(context)) {}
+
+template <class ELFT>
+bool HexagonExecutableWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  ExecutableWriter<ELFT>::createImplicitFiles(result);
+  // Add the default atoms as defined for hexagon
+  addDefaultAtoms();
+  result.push_back(std::move(_hexagonRuntimeFile));
+  return true;
+}
+
+template <class ELFT>
+void HexagonExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
+  // Finalize the atom values that are part of the parent.
+  ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+  auto sdabaseAtomIter = _hexagonTargetLayout.findAbsoluteAtom("_SDA_BASE_");
+  (*sdabaseAtomIter)->_virtualAddr =
+      _hexagonTargetLayout.getSDataSection()->virtualAddr();
+  HexagonELFWriter<ELFT>::finalizeHexagonRuntimeAtomValues();
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // HEXAGON_EXECUTABLE_WRITER_H

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Sun Jan 26 19:21:02 2014
@@ -18,6 +18,8 @@
 namespace lld {
 namespace elf {
 
+typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
+
 class HexagonLinkingContext LLVM_FINAL : public ELFLinkingContext {
 public:
   HexagonLinkingContext(llvm::Triple triple);

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp Sun Jan 26 19:21:02 2014
@@ -264,19 +264,19 @@ error_code HexagonTargetRelocationHandle
     break;
   case R_HEX_GPREL16_0:
     relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
-                   _targetLayout.getSDataSection()->virtualAddr(), 0);
+                   _hexagonTargetLayout.getSDataSection()->virtualAddr(), 0);
     break;
   case R_HEX_GPREL16_1:
     relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
-                   _targetLayout.getSDataSection()->virtualAddr(), 1);
+                   _hexagonTargetLayout.getSDataSection()->virtualAddr(), 1);
     break;
   case R_HEX_GPREL16_2:
     relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
-                   _targetLayout.getSDataSection()->virtualAddr(), 2);
+                   _hexagonTargetLayout.getSDataSection()->virtualAddr(), 2);
     break;
   case R_HEX_GPREL16_3:
     relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
-                   _targetLayout.getSDataSection()->virtualAddr(), 3);
+                   _hexagonTargetLayout.getSDataSection()->virtualAddr(), 3);
     break;
   case R_HEX_16_X:
   case R_HEX_12_X:
@@ -296,45 +296,52 @@ error_code HexagonTargetRelocationHandle
     break;
   case R_HEX_GOTREL_32:
     relocHexGOTREL_32(location, relocVAddress, targetVAddress, ref.addend(),
-                      _targetHandler.getGOTSymAddr());
+                      _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOTREL_LO16:
     relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
-                          _targetHandler.getGOTSymAddr());
+                          _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOTREL_HI16:
     relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
-                          _targetHandler.getGOTSymAddr(), 16);
+                          _hexagonTargetLayout.getGOTSymAddr(), 16);
     break;
   case R_HEX_GOT_LO16:
-    relocHexGOTLO16(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOTLO16(location, targetVAddress,
+                    _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOT_HI16:
-    relocHexGOTHI16(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOTHI16(location, targetVAddress,
+                    _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOT_32:
-    relocHexGOT32(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOT32(location, targetVAddress,
+                  _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOT_16:
-    relocHexGOT16(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOT16(location, targetVAddress,
+                  _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOT_32_6_X:
-    relocHexGOT32_6_X(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOT32_6_X(location, targetVAddress,
+                      _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOT_16_X:
-    relocHexGOT16_X(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOT16_X(location, targetVAddress,
+                    _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOT_11_X:
-    relocHexGOT11_X(location, targetVAddress, _targetHandler.getGOTSymAddr());
+    relocHexGOT11_X(location, targetVAddress,
+                    _hexagonTargetLayout.getGOTSymAddr());
     break;
   case R_HEX_GOTREL_32_6_X:
     relocHexGOTRELSigned(location, relocVAddress, targetVAddress, ref.addend(),
-                   _targetHandler.getGOTSymAddr(), 6);
+                         _hexagonTargetLayout.getGOTSymAddr(), 6);
     break;
   case R_HEX_GOTREL_16_X:
   case R_HEX_GOTREL_11_X:
-    relocHexGOTRELUnsigned(location, relocVAddress, targetVAddress, ref.addend(),
-                   _targetHandler.getGOTSymAddr());
+    relocHexGOTRELUnsigned(location, relocVAddress, targetVAddress,
+                           ref.addend(), _hexagonTargetLayout.getGOTSymAddr());
     break;
 
   default : {
@@ -349,4 +356,4 @@ error_code HexagonTargetRelocationHandle
   return error_code::success();
 }
 
- 
\ No newline at end of file
+

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h Sun Jan 26 19:21:02 2014
@@ -18,23 +18,21 @@ namespace elf {
 
 class HexagonLinkingContext;
 class HexagonTargetHandler;
-template <class HexagonELFType> class HexagonTargetLayout;
 
 class HexagonTargetRelocationHandler LLVM_FINAL :
     public TargetRelocationHandler<HexagonELFType> {
 public:
-  HexagonTargetRelocationHandler(
-      const HexagonLinkingContext &context, const HexagonTargetHandler &tH,
-      const HexagonTargetLayout<HexagonELFType> &layout)
-      : _targetHandler(tH), _targetLayout(layout) {}
+  HexagonTargetRelocationHandler(HexagonLinkingContext &context,
+                                 HexagonTargetLayout<HexagonELFType> &layout)
+      : _hexagonLinkingContext(context), _hexagonTargetLayout(layout) {}
 
-  virtual error_code
-  applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
-                  const lld::AtomLayout &, const Reference &) const;
+  virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
+                                     const lld::AtomLayout &,
+                                     const Reference &) const;
 
 private:
-  const HexagonTargetHandler &_targetHandler;
-  const HexagonTargetLayout<HexagonELFType> &_targetLayout;
+  HexagonLinkingContext &_hexagonLinkingContext LLVM_ATTRIBUTE_UNUSED;
+  HexagonTargetLayout<HexagonELFType> &_hexagonTargetLayout;
 };
 } // elf
 } // lld

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h Sun Jan 26 19:21:02 2014
@@ -6,14 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_SECTION_CHUNKS_H
-#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_SECTION_CHUNKS_H
+#ifndef HEXAGON_SECTION_CHUNKS_H
+#define HEXAGON_SECTION_CHUNKS_H
 
 #include "HexagonTargetHandler.h"
 
 namespace lld {
 namespace elf {
-typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
 template <typename ELFT> class HexagonTargetLayout;
 class HexagonLinkingContext;
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "HexagonExecutableWriter.h"
+#include "HexagonDynamicLibraryWriter.h"
 #include "HexagonTargetHandler.h"
 #include "HexagonLinkingContext.h"
 
@@ -17,11 +19,28 @@ using namespace llvm::ELF;
 using llvm::makeArrayRef;
 
 HexagonTargetHandler::HexagonTargetHandler(HexagonLinkingContext &context)
-    : DefaultTargetHandler(context), _targetLayout(context),
-      _relocationHandler(context, *this, _targetLayout),
-      _hexagonRuntimeFile(new HexagonRuntimeFile<HexagonELFType>(context)) {}
-
-namespace {
+    : DefaultTargetHandler(context), _hexagonLinkingContext(context),
+      _hexagonRuntimeFile(new HexagonRuntimeFile<HexagonELFType>(context)),
+      _hexagonTargetLayout(new HexagonTargetLayout<HexagonELFType>(context)),
+      _hexagonRelocationHandler(new HexagonTargetRelocationHandler(
+          context, *_hexagonTargetLayout.get())) {}
+
+std::unique_ptr<Writer> HexagonTargetHandler::getWriter() {
+  switch (_hexagonLinkingContext.getOutputELFType()) {
+  case llvm::ELF::ET_EXEC:
+    return std::unique_ptr<Writer>(
+        new elf::HexagonExecutableWriter<HexagonELFType>(
+            _hexagonLinkingContext, *_hexagonTargetLayout.get()));
+  case llvm::ELF::ET_DYN:
+    return std::unique_ptr<Writer>(
+        new elf::HexagonDynamicLibraryWriter<HexagonELFType>(
+            _hexagonLinkingContext, *_hexagonTargetLayout.get()));
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
+  }
+}
 
 using namespace llvm::ELF;
 
@@ -297,7 +316,6 @@ public:
     return error_code::success();
   }
 };
-} // end anonymous namespace
 
 void elf::HexagonLinkingContext::addPasses(PassManager &pm) {
   if (isDynamic())

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_TARGET_HANDLER_H
+#ifndef HEXAGON_TARGET_HANDLER_H
+#define HEXAGON_TARGET_HANDLER_H
 
 #include "DefaultTargetHandler.h"
 #include "HexagonExecutableAtoms.h"
@@ -25,14 +25,14 @@ class HexagonLinkingContext;
 /// \brief TargetLayout for Hexagon
 template <class HexagonELFType>
 class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> {
-
 public:
   enum HexagonSectionOrder {
     ORDER_SDATA = 205
   };
 
   HexagonTargetLayout(const HexagonLinkingContext &hti)
-      : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr) {
+      : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr),
+        _gotSymAtom(nullptr), _cachedGotSymAtom(false) {
     _sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti);
   }
 
@@ -84,9 +84,22 @@ public:
     return _sdataSection;
   }
 
+  uint64_t getGOTSymAddr() {
+    if (!_cachedGotSymAtom) {
+      auto gotAtomIter = this->findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      _gotSymAtom = (*gotAtomIter);
+      _cachedGotSymAtom = true;
+    }
+    if (_gotSymAtom)
+      return _gotSymAtom->_virtualAddr;
+    return 0;
+  }
+
 private:
   llvm::BumpPtrAllocator _alloc;
   SDataSection<HexagonELFType> *_sdataSection;
+  AtomLayout *_gotSymAtom;
+  bool _cachedGotSymAtom;
 };
 
 /// \brief TargetHandler for Hexagon
@@ -97,64 +110,12 @@ public:
 
   virtual void registerRelocationNames(Registry &registry);
 
-  bool doesOverrideELFHeader() { return true; }
-
-  void setELFHeader(ELFHeader<HexagonELFType> *elfHeader) {
-    elfHeader->e_ident(llvm::ELF::EI_VERSION, 1);
-    elfHeader->e_ident(llvm::ELF::EI_OSABI, 0);
-    elfHeader->e_version(1);
-    elfHeader->e_flags(0x3);
-  }
-
-  virtual HexagonTargetLayout<HexagonELFType> &targetLayout() {
-    return _targetLayout;
-  }
-
   virtual const HexagonTargetRelocationHandler &getRelocationHandler() const {
-    return _relocationHandler;
-  }
-
-  void addDefaultAtoms() {
-    _hexagonRuntimeFile->addAbsoluteAtom("_SDA_BASE_");
-    if (_context.isDynamic()) {
-      _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
-      _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
-    }
-  }
-
-  virtual bool
-  createImplicitFiles(std::vector<std::unique_ptr<File> > &result) {
-    // Add the default atoms as defined for hexagon
-    addDefaultAtoms();
-    result.push_back(std::move(_hexagonRuntimeFile));
-    return true;
-  }
-
-  void finalizeSymbolValues() {
-    auto sdabaseAtomIter = _targetLayout.findAbsoluteAtom("_SDA_BASE_");
-    (*sdabaseAtomIter)->_virtualAddr =
-        _targetLayout.getSDataSection()->virtualAddr();
-    if (_context.isDynamic()) {
-      auto gotAtomIter =
-          _targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
-      _gotSymAtom = (*gotAtomIter);
-      auto gotpltSection = _targetLayout.findOutputSection(".got.plt");
-      if (gotpltSection)
-        _gotSymAtom->_virtualAddr = gotpltSection->virtualAddr();
-      else
-        _gotSymAtom->_virtualAddr = 0;
-      auto dynamicAtomIter = _targetLayout.findAbsoluteAtom("_DYNAMIC");
-      auto dynamicSection = _targetLayout.findOutputSection(".dynamic");
-      if (dynamicSection)
-        (*dynamicAtomIter)->_virtualAddr = dynamicSection->virtualAddr();
-      else
-        (*dynamicAtomIter)->_virtualAddr = 0;
-    }
+    return *(_hexagonRelocationHandler.get());
   }
 
-  uint64_t getGOTSymAddr() const {
-    if (!_gotSymAtom) return 0;
-    return _gotSymAtom->_virtualAddr;
+  virtual HexagonTargetLayout<HexagonELFType> &getTargetLayout() {
+    return *(_hexagonTargetLayout.get());
   }
 
   virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
@@ -165,13 +126,15 @@ public:
     return std::unique_ptr<Reader>(new HexagonELFDSOReader(useShlibUndefines));
   }
 
+  virtual std::unique_ptr<Writer> getWriter();
+
 private:
+  llvm::BumpPtrAllocator _alloc;
   static const Registry::KindStrings kindStrings[];
-
-  HexagonTargetLayout<HexagonELFType> _targetLayout;
-  HexagonTargetRelocationHandler _relocationHandler;
+  HexagonLinkingContext &_hexagonLinkingContext;
   std::unique_ptr<HexagonRuntimeFile<HexagonELFType> > _hexagonRuntimeFile;
-  AtomLayout *_gotSymAtom;
+  std::unique_ptr<HexagonTargetLayout<HexagonELFType>> _hexagonTargetLayout;
+  std::unique_ptr<HexagonTargetRelocationHandler> _hexagonRelocationHandler;
 };
 } // end namespace elf
 } // end namespace lld

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,102 @@
+//===- 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 MIPS_DYNAMIC_LIBRARY_WRITER_H
+#define MIPS_DYNAMIC_LIBRARY_WRITER_H
+
+#include "DynamicLibraryWriter.h"
+#include "MipsELFWriters.h"
+#include "MipsLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class MipsTargetLayout;
+
+template <class ELFT>
+class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT>,
+                                 public MipsELFWriter<ELFT> {
+public:
+  MipsDynamicLibraryWriter(MipsLinkingContext &context,
+                           MipsTargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+  virtual void finalizeDefaultAtomValues();
+
+  virtual error_code setELFHeader() {
+    DynamicLibraryWriter<ELFT>::setELFHeader();
+    MipsELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+    return error_code::success();
+  }
+
+  LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
+
+  LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable();
+
+private:
+  void addDefaultAtoms() {
+    if (this->_context.isDynamic()) {
+      _mipsRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      _mipsRuntimeFile->addAbsoluteAtom("_gp");
+      _mipsRuntimeFile->addAbsoluteAtom("_gp_disp");
+    }
+  }
+
+  std::unique_ptr<MipsRuntimeFile<ELFT>> _mipsRuntimeFile;
+  MipsLinkingContext &_mipsContext;
+  MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
+
+template <class ELFT>
+MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
+    MipsLinkingContext &context, MipsTargetLayout<ELFT> &layout)
+    : DynamicLibraryWriter<ELFT>(context, layout),
+      MipsELFWriter<ELFT>(context, layout),
+      _mipsRuntimeFile(new MipsRuntimeFile<ELFT>(context)),
+      _mipsContext(context), _mipsTargetLayout(layout) {}
+
+template <class ELFT>
+bool MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+  // Add the default atoms as defined for mips
+  addDefaultAtoms();
+  result.push_back(std::move(_mipsRuntimeFile));
+  return true;
+}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+  // Finalize the atom values that are part of the parent.
+  DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+  MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues();
+}
+
+/// \brief create dynamic table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
+    MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
+  return LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)(new (
+      this->_alloc) MipsDynamicTable(_mipsContext, _mipsTargetLayout));
+}
+
+/// \brief create dynamic symbol table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+    MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
+  return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)(new (
+      this->_alloc) MipsDynamicSymbolTable(_mipsContext, _mipsTargetLayout));
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // MIPS_DYNAMIC_LIBRARY_WRITER_H

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,75 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsELFWriters.h -------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MIPS_ELF_WRITERS_H
+#define MIPS_ELF_WRITERS_H
+
+#include "MipsLinkingContext.h"
+#include "OutputELFWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class MipsTargetLayout;
+
+template <typename ELFT> class MipsELFWriter {
+public:
+  MipsELFWriter(MipsLinkingContext &context,
+                MipsTargetLayout<ELFT> &targetLayout)
+      : _mipsLinkingContext(context), _mipsTargetLayout(targetLayout) {}
+
+protected:
+  bool 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 (_mipsTargetLayout.findOutputSection(".got.plt"))
+      elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1);
+    else
+      elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
+
+    // FIXME (simon): Read elf flags from all inputs, check compatibility,
+    // merge them and write result here.
+    uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 |
+                     llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2;
+    if (_mipsLinkingContext.getOutputELFType() == llvm::ELF::ET_DYN)
+      flags |= EF_MIPS_PIC;
+    elfHeader.e_flags(flags);
+    return true;
+  }
+
+  void finalizeMipsRuntimeAtomValues() {
+    if (_mipsLinkingContext.isDynamic()) {
+      auto gotSection = _mipsTargetLayout.findOutputSection(".got");
+      auto got = gotSection ? gotSection->virtualAddr() : 0;
+      auto gp = gotSection ? got + _mipsTargetLayout.getGPOffset() : 0;
+
+      auto gotAtomIter =
+          _mipsTargetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      assert(gotAtomIter != _mipsTargetLayout.absoluteAtoms().end());
+      (*gotAtomIter)->_virtualAddr = got;
+
+      auto gpAtomIter = _mipsTargetLayout.findAbsoluteAtom("_gp");
+      assert(gpAtomIter != _mipsTargetLayout.absoluteAtoms().end());
+      (*gpAtomIter)->_virtualAddr = gp;
+
+      AtomLayout *gpAtom = _mipsTargetLayout.getGP();
+      assert(gpAtom != nullptr);
+      gpAtom->_virtualAddr = gp;
+    }
+  }
+
+private:
+  MipsLinkingContext &_mipsLinkingContext LLVM_ATTRIBUTE_UNUSED;
+  MipsTargetLayout<ELFT> &_mipsTargetLayout;
+};
+
+} // elf
+} // lld
+#endif // MIPS_ELF_WRITERS_H

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,102 @@
+//===- 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 MIPS_EXECUTABLE_WRITER_H
+#define MIPS_EXECUTABLE_WRITER_H
+
+#include "ExecutableWriter.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 MipsELFWriter<ELFT> {
+public:
+  MipsExecutableWriter(MipsLinkingContext &context,
+                       MipsTargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+  virtual void finalizeDefaultAtomValues();
+
+  virtual error_code setELFHeader() {
+    ExecutableWriter<ELFT>::setELFHeader();
+    MipsELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+    return error_code::success();
+  }
+
+  LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
+
+  LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable();
+
+private:
+  void addDefaultAtoms() {
+    if (this->_context.isDynamic()) {
+      _mipsRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      _mipsRuntimeFile->addAbsoluteAtom("_gp");
+      _mipsRuntimeFile->addAbsoluteAtom("_gp_disp");
+    }
+  }
+
+  std::unique_ptr<MipsRuntimeFile<ELFT>> _mipsRuntimeFile;
+  MipsLinkingContext &_mipsContext;
+  MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
+
+template <class ELFT>
+MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &context,
+                                                 MipsTargetLayout<ELFT> &layout)
+    : ExecutableWriter<ELFT>(context, layout),
+      MipsELFWriter<ELFT>(context, layout),
+      _mipsRuntimeFile(new MipsRuntimeFile<ELFT>(context)),
+      _mipsContext(context), _mipsTargetLayout(layout) {}
+
+template <class ELFT>
+bool MipsExecutableWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  ExecutableWriter<ELFT>::createImplicitFiles(result);
+  // Add the default atoms as defined for mips
+  addDefaultAtoms();
+  result.push_back(std::move(_mipsRuntimeFile));
+  return true;
+}
+
+template <class ELFT>
+void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
+  // Finalize the atom values that are part of the parent.
+  ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+  MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues();
+}
+
+/// \brief create dynamic table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
+    MipsExecutableWriter<ELFT>::createDynamicTable() {
+  return LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)(new (
+      this->_alloc) MipsDynamicTable(_mipsContext, _mipsTargetLayout));
+}
+
+/// \brief create dynamic symbol table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+    MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
+  return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)(new (
+      this->_alloc) MipsDynamicSymbolTable(_mipsContext, _mipsTargetLayout));
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // MIPS_EXECUTABLE_WRITER_H

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=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Sun Jan 26 19:21:02 2014
@@ -19,17 +19,6 @@ MipsLinkingContext::MipsLinkingContext(l
     : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
                                     new MipsTargetHandler(*this))) {}
 
-MipsTargetLayout<Mips32ElELFType> &MipsLinkingContext::getTargetLayout() {
-  auto &layout = getTargetHandler<Mips32ElELFType>().targetLayout();
-  return static_cast<MipsTargetLayout<Mips32ElELFType> &>(layout);
-}
-
-const MipsTargetLayout<Mips32ElELFType> &
-MipsLinkingContext::getTargetLayout() const {
-  auto &layout = getTargetHandler<Mips32ElELFType>().targetLayout();
-  return static_cast<MipsTargetLayout<Mips32ElELFType> &>(layout);
-}
-
 bool MipsLinkingContext::isLittleEndian() const {
   return Mips32ElELFType::TargetEndianness == llvm::support::little;
 }

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=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Sun Jan 26 19:21:02 2014
@@ -112,10 +112,6 @@ void relocLldLo16(uint8_t *location, uin
 
 } // end anon namespace
 
-MipsTargetRelocationHandler::MipsTargetRelocationHandler(
-    const MipsLinkingContext &context, const MipsTargetHandler &handler)
-    : _targetHandler(handler) {}
-
 MipsTargetRelocationHandler::~MipsTargetRelocationHandler() {
   assert(_pairedRelocations.empty());
 }
@@ -132,7 +128,7 @@ MipsTargetRelocationHandler::savePairedR
 
 void MipsTargetRelocationHandler::applyPairedRelocations(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
-    int64_t loAddend) const {
+    int64_t gpAddr, int64_t loAddend) const {
   auto pi = _pairedRelocations.find(&atom);
   if (pi == _pairedRelocations.end())
     return;
@@ -150,13 +146,11 @@ void MipsTargetRelocationHandler::applyP
     assert(ri->kindArch() == Reference::KindArch::Mips);
     switch (ri->kindValue()) {
     case R_MIPS_HI16:
-      relocHi16(location, relocVAddress, targetVAddress, ahl,
-                _targetHandler.getGPDispSymAddr(),
+      relocHi16(location, relocVAddress, targetVAddress, ahl, gpAddr,
                 ri->target()->name() == "_gp_disp");
       break;
     case R_MIPS_GOT16:
-      relocGOT16(location, relocVAddress, targetVAddress, ahl,
-                 _targetHandler.getGPDispSymAddr());
+      relocGOT16(location, relocVAddress, targetVAddress, ahl, gpAddr);
       break;
     default:
       llvm_unreachable("Unknown type of paired relocation.");
@@ -169,6 +163,9 @@ void MipsTargetRelocationHandler::applyP
 error_code MipsTargetRelocationHandler::applyRelocation(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
     const Reference &ref) const {
+  AtomLayout *gpAtom = _mipsTargetLayout.getGP();
+  uint64_t gpAddr = gpAtom ? gpAtom->_virtualAddr : 0;
+
   uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
   uint8_t *location = atomContent + ref.offsetInAtom();
   uint64_t targetVAddress = writer.addressOfAtom(ref.target());
@@ -191,16 +188,14 @@ error_code MipsTargetRelocationHandler::
     break;
   case R_MIPS_LO16:
     relocLo16(location, relocVAddress, targetVAddress, calcAHL(0, ref.addend()),
-              _targetHandler.getGPDispSymAddr(),
-              ref.target()->name() == "_gp_disp");
-    applyPairedRelocations(writer, buf, atom, ref.addend());
+              gpAddr, ref.target()->name() == "_gp_disp");
+    applyPairedRelocations(writer, buf, atom, gpAddr, ref.addend());
     break;
   case R_MIPS_GOT16:
     savePairedRelocation(atom, ref);
     break;
   case R_MIPS_CALL16:
-    relocCall16(location, relocVAddress, targetVAddress, ref.addend(),
-                _targetHandler.getGPDispSymAddr());
+    relocCall16(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
     break;
   case R_MIPS_JALR:
     // We do not do JALR optimization now.
@@ -212,8 +207,7 @@ error_code MipsTargetRelocationHandler::
     // Do nothing.
     break;
   case LLD_R_MIPS_GLOBAL_GOT16:
-    relocGOT16(location, relocVAddress, targetVAddress, ref.addend(),
-               _targetHandler.getGPDispSymAddr());
+    relocGOT16(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
     break;
   case LLD_R_MIPS_GLOBAL_26:
     reloc26(location, relocVAddress, targetVAddress, false);

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h Sun Jan 26 19:21:02 2014
@@ -19,8 +19,9 @@ class MipsTargetHandler;
 class MipsTargetRelocationHandler LLVM_FINAL
     : public TargetRelocationHandler<Mips32ElELFType> {
 public:
-  MipsTargetRelocationHandler(const MipsLinkingContext &context,
-                              const MipsTargetHandler &handler);
+  MipsTargetRelocationHandler(MipsLinkingContext &context,
+                              MipsTargetLayout<Mips32ElELFType> &layout)
+      : _mipsLinkingContext(context), _mipsTargetLayout(layout) {}
 
   ~MipsTargetRelocationHandler();
 
@@ -29,8 +30,6 @@ public:
                                      const Reference &) const;
 
 private:
-  const MipsTargetHandler &_targetHandler;
-
   typedef std::vector<const Reference *> PairedRelocationsT;
   typedef std::unordered_map<const lld::AtomLayout *, PairedRelocationsT>
   PairedRelocationMapT;
@@ -40,8 +39,11 @@ private:
   void savePairedRelocation(const lld::AtomLayout &atom,
                             const Reference &ref) const;
   void applyPairedRelocations(ELFWriter &writer, llvm::FileOutputBuffer &buf,
-                              const lld::AtomLayout &atom,
+                              const lld::AtomLayout &atom, int64_t gpAddr,
                               int64_t loAddend) const;
+
+  MipsLinkingContext &_mipsLinkingContext LLVM_ATTRIBUTE_UNUSED;
+  MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
 };
 
 } // elf

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -10,201 +10,35 @@
 #include "ELFFile.h"
 #include "MipsLinkingContext.h"
 #include "MipsTargetHandler.h"
+#include "MipsExecutableWriter.h"
+#include "MipsDynamicLibraryWriter.h"
 
 using namespace lld;
 using namespace elf;
 
-namespace {
-
-class MipsDynamicSymbolTable : public DynamicSymbolTable<Mips32ElELFType> {
-public:
-  MipsDynamicSymbolTable(const MipsLinkingContext &context)
-      : DynamicSymbolTable<Mips32ElELFType>(
-            context, ".dynsym",
-            DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC_SYMBOLS),
-        _layout(context.getTargetLayout()) {}
-
-  virtual void sortSymbols() {
-    std::stable_sort(_symbolTable.begin(), _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 _layout.getGOTSection().compare(A._atom, B._atom);
-    });
-  }
-
-private:
-  const MipsTargetLayout<Mips32ElELFType> &_layout;
-};
-
-class MipsDynamicTable : public DynamicTable<Mips32ElELFType> {
-public:
-  MipsDynamicTable(MipsLinkingContext &context)
-      : DynamicTable<Mips32ElELFType>(
-            context, ".dynamic", DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC),
-        _layout(context.getTargetLayout()) {}
-
-  virtual void createDefaultEntries() {
-    DynamicTable<Mips32ElELFType>::createDefaultEntries();
-
-    Elf_Dyn dyn;
-
-    // Version id for the Runtime Linker Interface.
-    dyn.d_un.d_val = 1;
-    dyn.d_tag = DT_MIPS_RLD_VERSION;
-    addEntry(dyn);
-
-    // MIPS flags.
-    dyn.d_un.d_val = RHF_NOTPOT;
-    dyn.d_tag = DT_MIPS_FLAGS;
-    addEntry(dyn);
-
-    // The base address of the segment.
-    dyn.d_un.d_ptr = 0;
-    dyn.d_tag = DT_MIPS_BASE_ADDRESS;
-    _dt_baseaddr = addEntry(dyn);
-
-    // Number of local global offset table entries.
-    dyn.d_un.d_val = 0;
-    dyn.d_tag = DT_MIPS_LOCAL_GOTNO;
-    _dt_localgot = addEntry(dyn);
-
-    // Number of entries in the .dynsym section.
-    dyn.d_un.d_val = 0;
-    dyn.d_tag = DT_MIPS_SYMTABNO;
-    _dt_symtabno = addEntry(dyn);
-
-    // The index of the first dynamic symbol table entry that corresponds
-    // to an entry in the global offset table.
-    dyn.d_un.d_val = 0;
-    dyn.d_tag = DT_MIPS_GOTSYM;
-    _dt_gotsym = addEntry(dyn);
-
-    // Address of the .got section.
-    dyn.d_un.d_val = 0;
-    dyn.d_tag = DT_PLTGOT;
-    _dt_pltgot = addEntry(dyn);
-  }
-
-  virtual void updateDynamicTable() {
-    DynamicTable<Mips32ElELFType>::updateDynamicTable();
-
-    // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag.
-    auto baseAddr = std::numeric_limits<uint64_t>::max();
-    for (auto si : _layout.segments())
-      if (si->segmentType() != llvm::ELF::PT_NULL)
-        baseAddr = std::min(baseAddr, si->virtualAddr());
-    _entries[_dt_baseaddr].d_un.d_val = baseAddr;
-
-    auto &got = _layout.getGOTSection();
-
-    _entries[_dt_symtabno].d_un.d_val = getSymbolTable()->size();
-    _entries[_dt_gotsym].d_un.d_val =
-        getSymbolTable()->size() - got.getGlobalCount();
-    _entries[_dt_localgot].d_un.d_val = got.getLocalCount();
-    _entries[_dt_pltgot].d_un.d_ptr =
-        _layout.findOutputSection(".got")->virtualAddr();
-  }
-
-private:
-  MipsTargetLayout<Mips32ElELFType> &_layout;
-
-  std::size_t _dt_symtabno;
-  std::size_t _dt_localgot;
-  std::size_t _dt_gotsym;
-  std::size_t _dt_pltgot;
-  std::size_t _dt_baseaddr;
-};
-}
+typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType;
 
 MipsTargetHandler::MipsTargetHandler(MipsLinkingContext &context)
-    : DefaultTargetHandler(context), _targetLayout(context),
-      _relocationHandler(context, *this), _gpDispSymAtom(nullptr) {}
-
-uint64_t MipsTargetHandler::getGPDispSymAddr() const {
-  return _gpDispSymAtom ? _gpDispSymAtom->_virtualAddr : 0;
-}
-
-bool MipsTargetHandler::doesOverrideELFHeader() { return true; }
-
-void MipsTargetHandler::setELFHeader(ELFHeader<Mips32ElELFType> *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);
-
-  // FIXME (simon): Read elf flags from all inputs, check compatibility,
-  // merge them and write result here.
-  uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 |
-                   llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2;
-  if (_context.getOutputELFType() == llvm::ELF::ET_DYN)
-    flags |= EF_MIPS_PIC;
-  elfHeader->e_flags(flags);
-}
-
-MipsTargetLayout<Mips32ElELFType> &MipsTargetHandler::targetLayout() {
-  return _targetLayout;
-}
-
-const MipsTargetRelocationHandler &
-MipsTargetHandler::getRelocationHandler() const {
-  return _relocationHandler;
-}
-
-LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)
-MipsTargetHandler::createDynamicTable() {
-  return LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)(
-      new (_alloc) MipsDynamicTable(
-          static_cast<MipsLinkingContext &>(_context)));
-}
-
-LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)
-MipsTargetHandler::createDynamicSymbolTable() {
-  return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)(
-      new (_alloc) MipsDynamicSymbolTable(
-          static_cast<MipsLinkingContext &>(_context)));
-}
-
-bool MipsTargetHandler::createImplicitFiles(
-    std::vector<std::unique_ptr<File>> &result) {
-  typedef CRuntimeFile<Mips32ElELFType> RFile;
-  auto file = std::unique_ptr<RFile>(new RFile(_context, "MIPS runtime file"));
-
-  if (_context.isDynamic()) {
-    file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
-    file->addAbsoluteAtom("_gp");
-    file->addAbsoluteAtom("_gp_disp");
-  }
-  result.push_back(std::move(file));
-  return true;
-}
-
-void MipsTargetHandler::finalizeSymbolValues() {
-  DefaultTargetHandler<Mips32ElELFType>::finalizeSymbolValues();
-
-  if (_context.isDynamic()) {
-    auto gotSection = _targetLayout.findOutputSection(".got");
-    auto got = gotSection ? gotSection->virtualAddr() : 0;
-    auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
-
-    auto gotAtomIter = _targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
-    assert(gotAtomIter != _targetLayout.absoluteAtoms().end());
-    (*gotAtomIter)->_virtualAddr = got;
-
-    auto gpAtomIter = _targetLayout.findAbsoluteAtom("_gp");
-    assert(gpAtomIter != _targetLayout.absoluteAtoms().end());
-    (*gpAtomIter)->_virtualAddr = gp;
-
-    auto gpDispAtomIter = _targetLayout.findAbsoluteAtom("_gp_disp");
-    assert(gpDispAtomIter != _targetLayout.absoluteAtoms().end());
-    _gpDispSymAtom = (*gpDispAtomIter);
-    _gpDispSymAtom->_virtualAddr = gp;
+    : DefaultTargetHandler(context), _mipsLinkingContext(context),
+      _mipsRuntimeFile(new MipsRuntimeFile<Mips32ElELFType>(context)),
+      _mipsTargetLayout(new MipsTargetLayout<Mips32ElELFType>(context)),
+      _mipsRelocationHandler(
+          new MipsTargetRelocationHandler(context, *_mipsTargetLayout.get())) {}
+
+std::unique_ptr<Writer> MipsTargetHandler::getWriter() {
+  switch (_mipsLinkingContext.getOutputELFType()) {
+  case llvm::ELF::ET_EXEC:
+    return std::unique_ptr<Writer>(
+        new elf::MipsExecutableWriter<Mips32ElELFType>(
+            _mipsLinkingContext, *_mipsTargetLayout.get()));
+  case llvm::ELF::ET_DYN:
+    return std::unique_ptr<Writer>(
+        new elf::MipsDynamicLibraryWriter<Mips32ElELFType>(
+            _mipsLinkingContext, *_mipsTargetLayout.get()));
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
   }
 }
 

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=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -24,10 +24,8 @@ class MipsTargetLayout LLVM_FINAL : publ
 public:
   MipsTargetLayout(const MipsLinkingContext &ctx)
       : TargetLayout<ELFType>(ctx),
-        _gotSection(new (_alloc) MipsGOTSection<ELFType>(ctx)) {}
-
-  /// \brief GP offset relative to .got section.
-  uint64_t getGPOffset() const { return 0x7FF0; }
+        _gotSection(new (_alloc) MipsGOTSection<ELFType>(ctx)),
+        _cachedGP(false) {}
 
   const MipsGOTSection<ELFType> &getGOTSection() const { return *_gotSection; }
 
@@ -41,39 +39,162 @@ public:
                                                  order);
   }
 
+  /// \brief GP offset relative to .got section.
+  uint64_t getGPOffset() const { return 0x7FF0; }
+
+  /// \brief Get the cached value of the GP atom.
+  AtomLayout *getGP() {
+    if (!_cachedGP) {
+      auto gpAtomIter = this->findAbsoluteAtom("_gp_disp");
+      _gp = *(gpAtomIter);
+      _cachedGP = true;
+    }
+    return _gp;
+  }
+
 private:
   llvm::BumpPtrAllocator _alloc;
   MipsGOTSection<ELFType> *_gotSection;
+  AtomLayout *_gp;
+  bool _cachedGP;
+};
+
+/// \brief Mips Runtime file.
+template <class ELFType> class MipsRuntimeFile : public CRuntimeFile<ELFType> {
+public:
+  MipsRuntimeFile(const MipsLinkingContext &context)
+      : CRuntimeFile<ELFType>(context, "Mips runtime file") {}
 };
 
 /// \brief TargetHandler for Mips
 class MipsTargetHandler LLVM_FINAL
     : public DefaultTargetHandler<Mips32ElELFType> {
 public:
-  MipsTargetHandler(MipsLinkingContext &targetInfo);
+  MipsTargetHandler(MipsLinkingContext &context);
+
+  virtual MipsTargetLayout<Mips32ElELFType> &getTargetLayout() {
+    return *(_mipsTargetLayout.get());
+  }
+
+  virtual const MipsTargetRelocationHandler &getRelocationHandler() const {
+    return *(_mipsRelocationHandler.get());
+  }
 
-  uint64_t getGPDispSymAddr() const;
+  virtual std::unique_ptr<Writer> getWriter();
 
-  virtual bool doesOverrideELFHeader();
-  virtual void setELFHeader(ELFHeader<Mips32ElELFType> *elfHeader);
-  virtual MipsTargetLayout<Mips32ElELFType> &targetLayout();
-  virtual const MipsTargetRelocationHandler &getRelocationHandler() const;
-  virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)
-  createDynamicTable();
-  virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)
-  createDynamicSymbolTable();
-  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &result);
-  virtual void finalizeSymbolValues();
   virtual void registerRelocationNames(Registry &registry);
 
 private:
   static const Registry::KindStrings kindStrings[];
-  llvm::BumpPtrAllocator _alloc;
-  MipsTargetLayout<Mips32ElELFType> _targetLayout;
-  MipsTargetRelocationHandler _relocationHandler;
-  AtomLayout *_gpDispSymAtom;
+  MipsLinkingContext &_mipsLinkingContext;
+  std::unique_ptr<MipsRuntimeFile<Mips32ElELFType>> _mipsRuntimeFile;
+  std::unique_ptr<MipsTargetLayout<Mips32ElELFType>> _mipsTargetLayout;
+  std::unique_ptr<MipsTargetRelocationHandler> _mipsRelocationHandler;
 };
 
+class MipsDynamicSymbolTable : public DynamicSymbolTable<Mips32ElELFType> {
+public:
+  MipsDynamicSymbolTable(const MipsLinkingContext &context,
+                         MipsTargetLayout<Mips32ElELFType> &layout)
+      : DynamicSymbolTable<Mips32ElELFType>(
+            context, layout, ".dynsym",
+            DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC_SYMBOLS),
+        _mipsTargetLayout(layout) {}
+
+  virtual void sortSymbols() {
+    std::stable_sort(_symbolTable.begin(), _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 _mipsTargetLayout.getGOTSection().compare(A._atom, B._atom);
+    });
+  }
+
+private:
+  MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
+
+class MipsDynamicTable : public DynamicTable<Mips32ElELFType> {
+public:
+  MipsDynamicTable(MipsLinkingContext &context,
+                   MipsTargetLayout<Mips32ElELFType> &layout)
+      : DynamicTable<Mips32ElELFType>(
+            context, layout, ".dynamic",
+            DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC),
+        _mipsTargetLayout(layout) {}
+
+  virtual void createDefaultEntries() {
+    DynamicTable<Mips32ElELFType>::createDefaultEntries();
+
+    Elf_Dyn dyn;
+
+    // Version id for the Runtime Linker Interface.
+    dyn.d_un.d_val = 1;
+    dyn.d_tag = DT_MIPS_RLD_VERSION;
+    addEntry(dyn);
+
+    // MIPS flags.
+    dyn.d_un.d_val = RHF_NOTPOT;
+    dyn.d_tag = DT_MIPS_FLAGS;
+    addEntry(dyn);
+
+    // The base address of the segment.
+    dyn.d_un.d_ptr = 0;
+    dyn.d_tag = DT_MIPS_BASE_ADDRESS;
+    _dt_baseaddr = addEntry(dyn);
+
+    // Number of local global offset table entries.
+    dyn.d_un.d_val = 0;
+    dyn.d_tag = DT_MIPS_LOCAL_GOTNO;
+    _dt_localgot = addEntry(dyn);
+
+    // Number of entries in the .dynsym section.
+    dyn.d_un.d_val = 0;
+    dyn.d_tag = DT_MIPS_SYMTABNO;
+    _dt_symtabno = addEntry(dyn);
+
+    // The index of the first dynamic symbol table entry that corresponds
+    // to an entry in the global offset table.
+    dyn.d_un.d_val = 0;
+    dyn.d_tag = DT_MIPS_GOTSYM;
+    _dt_gotsym = addEntry(dyn);
+
+    // Address of the .got section.
+    dyn.d_un.d_val = 0;
+    dyn.d_tag = DT_PLTGOT;
+    _dt_pltgot = addEntry(dyn);
+  }
+
+  virtual void updateDynamicTable() {
+    DynamicTable<Mips32ElELFType>::updateDynamicTable();
+
+    // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag.
+    auto baseAddr = std::numeric_limits<uint64_t>::max();
+    for (auto si : _mipsTargetLayout.segments())
+      if (si->segmentType() != llvm::ELF::PT_NULL)
+        baseAddr = std::min(baseAddr, si->virtualAddr());
+    _entries[_dt_baseaddr].d_un.d_val = baseAddr;
+
+    auto &got = _mipsTargetLayout.getGOTSection();
+
+    _entries[_dt_symtabno].d_un.d_val = getSymbolTable()->size();
+    _entries[_dt_gotsym].d_un.d_val =
+        getSymbolTable()->size() - got.getGlobalCount();
+    _entries[_dt_localgot].d_un.d_val = got.getLocalCount();
+    _entries[_dt_pltgot].d_un.d_ptr =
+        _mipsTargetLayout.findOutputSection(".got")->virtualAddr();
+  }
+
+private:
+  std::size_t _dt_symtabno;
+  std::size_t _dt_localgot;
+  std::size_t _dt_gotsym;
+  std::size_t _dt_pltgot;
+  std::size_t _dt_baseaddr;
+  MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
 } // end namespace elf
 } // end namespace lld
 

Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Sun Jan 26 19:21:02 2014
@@ -26,6 +26,7 @@ using namespace llvm;
 using namespace llvm::object;
 
 template <class ELFT> class OutputELFWriter;
+template <class ELFT> class TargetLayout;
 
 //===----------------------------------------------------------------------===//
 //  OutputELFWriter Class
@@ -41,7 +42,7 @@ public:
   typedef Elf_Sym_Impl<ELFT> Elf_Sym;
   typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
 
-  OutputELFWriter(const ELFLinkingContext &context);
+  OutputELFWriter(const ELFLinkingContext &context, TargetLayout<ELFT> &layout);
 
 protected:
   // build the sections that need to be created
@@ -100,6 +101,13 @@ protected:
   // This is a hook for creating default dynamic entries
   virtual void createDefaultDynamicEntries() {}
 
+  /// \brief create dynamic table.
+  virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
+
+  /// \brief create dynamic symbol table.
+  virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+      createDynamicSymbolTable();
+
   llvm::BumpPtrAllocator _alloc;
 
   const ELFLinkingContext &_context;
@@ -107,7 +115,7 @@ protected:
 
   typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
   AtomToAddress _atomToAddressMap;
-  TargetLayout<ELFT> *_layout;
+  TargetLayout<ELFT> &_layout;
   LLD_UNIQUE_BUMP_PTR(ELFHeader<ELFT>) _elfHeader;
   LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
   LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
@@ -129,29 +137,29 @@ protected:
 //  OutputELFWriter
 //===----------------------------------------------------------------------===//
 template <class ELFT>
-OutputELFWriter<ELFT>::OutputELFWriter(const ELFLinkingContext &context)
-    : _context(context), _targetHandler(context.getTargetHandler<ELFT>()) {
-  _layout = &_targetHandler.targetLayout();
-}
+OutputELFWriter<ELFT>::OutputELFWriter(const ELFLinkingContext &context,
+                                       TargetLayout<ELFT> &layout)
+    : _context(context), _targetHandler(context.getTargetHandler<ELFT>()),
+      _layout(layout) {}
 
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildChunks(const File &file) {
   ScopedTask task(getDefaultDomain(), "buildChunks");
   for (const DefinedAtom *definedAtom : file.defined()) {
-    _layout->addAtom(definedAtom);
+    _layout.addAtom(definedAtom);
   }
   for (const AbsoluteAtom *absoluteAtom : file.absolute())
-    _layout->addAtom(absoluteAtom);
+    _layout.addAtom(absoluteAtom);
 }
 
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) {
   ScopedTask task(getDefaultDomain(), "buildStaticSymbolTable");
-  for (auto sec : _layout->sections())
+  for (auto sec : _layout.sections())
     if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
       for (const auto &atom : section->atoms())
         _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
-  for (auto &atom : _layout->absoluteAtoms())
+  for (auto &atom : _layout.absoluteAtoms())
     _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
   for (const UndefinedAtom *a : file.undefined())
     _symtab->addSymbol(a, ELF::SHN_UNDEF);
@@ -160,7 +168,7 @@ void OutputELFWriter<ELFT>::buildStaticS
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
   ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
-  for (auto sec : this->_layout->sections())
+  for (auto sec : this->_layout.sections())
     if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
       for (const auto &atom : section->atoms()) {
         const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
@@ -208,17 +216,17 @@ void OutputELFWriter<ELFT>::buildDynamic
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildAtomToAddressMap(const File &file) {
   ScopedTask task(getDefaultDomain(), "buildAtomToAddressMap");
-  int64_t totalAbsAtoms = _layout->absoluteAtoms().size();
+  int64_t totalAbsAtoms = _layout.absoluteAtoms().size();
   int64_t totalUndefinedAtoms = file.undefined().size();
   int64_t totalDefinedAtoms = 0;
-  for (auto sec : _layout->sections())
+  for (auto sec : _layout.sections())
     if (auto section = dyn_cast<AtomSection<ELFT> >(sec)) {
       totalDefinedAtoms += section->atoms().size();
       for (const auto &atom : section->atoms())
         _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
     }
   // build the atomToAddressMap that contains absolute symbols too
-  for (auto &atom : _layout->absoluteAtoms())
+  for (auto &atom : _layout.absoluteAtoms())
     _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
 
   // Set the total number of atoms in the symbol table, so that appropriate
@@ -230,7 +238,7 @@ void OutputELFWriter<ELFT>::buildAtomToA
 template<class ELFT>
 void OutputELFWriter<ELFT>::buildSectionHeaderTable() {
   ScopedTask task(getDefaultDomain(), "buildSectionHeaderTable");
-  for (auto mergedSec : _layout->mergedSections()) {
+  for (auto mergedSec : _layout.mergedSections()) {
     if (mergedSec->kind() != Chunk<ELFT>::Kind::ELFSection &&
         mergedSec->kind() != Chunk<ELFT>::Kind::AtomSection)
       continue;
@@ -242,15 +250,15 @@ void OutputELFWriter<ELFT>::buildSection
 template<class ELFT>
 void OutputELFWriter<ELFT>::assignSectionsWithNoSegments() {
   ScopedTask task(getDefaultDomain(), "assignSectionsWithNoSegments");
-  for (auto mergedSec : _layout->mergedSections()) {
+  for (auto mergedSec : _layout.mergedSections()) {
     if (mergedSec->kind() != Chunk<ELFT>::Kind::ELFSection &&
         mergedSec->kind() != Chunk<ELFT>::Kind::AtomSection)
       continue;
     if (!mergedSec->hasSegment())
       _shdrtab->appendSection(mergedSec);
   }
-  _layout->assignOffsetsForMiscSections();
-  for (auto sec : _layout->sections())
+  _layout.assignOffsetsForMiscSections();
+  for (auto sec : _layout.sections())
     if (auto section = dyn_cast<Section<ELFT>>(sec))
       if (!DefaultLayout<ELFT>::hasOutputSegment(section))
         _shdrtab->updateSection(section);
@@ -258,17 +266,15 @@ void OutputELFWriter<ELFT>::assignSectio
 
 template <class ELFT>
 bool OutputELFWriter<ELFT>::createImplicitFiles(
-    std::vector<std::unique_ptr<File> > &result) {
-  // Add all input Files that are defined by the target
-  _targetHandler.createImplicitFiles(result);
+    std::vector<std::unique_ptr<File>> &) {
   return true;
 }
 
 template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
   _elfHeader.reset(new (_alloc) ELFHeader<ELFT>(_context));
   _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_context));
-  _layout->setHeader(_elfHeader.get());
-  _layout->setProgramHeader(_programHeader.get());
+  _layout.setHeader(_elfHeader.get());
+  _layout.setProgramHeader(_programHeader.get());
 
   _symtab.reset(new (_alloc) SymbolTable<ELFT>(
       _context, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
@@ -278,50 +284,67 @@ template <class ELFT> void OutputELFWrit
       _context, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
   _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
       _context, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
-  _layout->addSection(_symtab.get());
-  _layout->addSection(_strtab.get());
-  _layout->addSection(_shstrtab.get());
+  _layout.addSection(_symtab.get());
+  _layout.addSection(_strtab.get());
+  _layout.addSection(_shstrtab.get());
   _shdrtab->setStringSection(_shstrtab.get());
   _symtab->setStringSection(_strtab.get());
-  _layout->addSection(_shdrtab.get());
+  _layout.addSection(_shdrtab.get());
 
-  for (auto sec : _layout->sections()) {
+  for (auto sec : _layout.sections()) {
     if (sec->name() != ".eh_frame")
       continue;
     _ehFrameHeader.reset(new (_alloc) EHFrameHeader<ELFT>(
-        _context, ".eh_frame_hdr", DefaultLayout<ELFT>::ORDER_EH_FRAMEHDR));
-    _layout->addSection(_ehFrameHeader.get());
+        _context, ".eh_frame_hdr", _layout,
+        DefaultLayout<ELFT>::ORDER_EH_FRAMEHDR));
+    _layout.addSection(_ehFrameHeader.get());
     break;
   }
 
   if (_context.isDynamic()) {
-    _dynamicTable = std::move(_targetHandler.createDynamicTable());
+    _dynamicTable = std::move(createDynamicTable());
     _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
         _context, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS, true));
-    _dynamicSymbolTable = std::move(_targetHandler.createDynamicSymbolTable());
+    _dynamicSymbolTable = std::move(createDynamicSymbolTable());
     _hashTable.reset(new (_alloc) HashSection<ELFT>(
         _context, ".hash", DefaultLayout<ELFT>::ORDER_HASH));
     // Set the hash table in the dynamic symbol table so that the entries in the
     // hash table can be created
     _dynamicSymbolTable->setHashTable(_hashTable.get());
     _hashTable->setSymbolTable(_dynamicSymbolTable.get());
-    _layout->addSection(_dynamicTable.get());
-    _layout->addSection(_dynamicStringTable.get());
-    _layout->addSection(_dynamicSymbolTable.get());
-    _layout->addSection(_hashTable.get());
+    _layout.addSection(_dynamicTable.get());
+    _layout.addSection(_dynamicStringTable.get());
+    _layout.addSection(_dynamicSymbolTable.get());
+    _layout.addSection(_hashTable.get());
     _dynamicSymbolTable->setStringSection(_dynamicStringTable.get());
     _dynamicTable->setSymbolTable(_dynamicSymbolTable.get());
     _dynamicTable->setHashTable(_hashTable.get());
-    if (_layout->hasDynamicRelocationTable())
-      _layout->getDynamicRelocationTable()
-          ->setSymbolTable(_dynamicSymbolTable.get());
-    if (_layout->hasPLTRelocationTable())
-      _layout->getPLTRelocationTable()->setSymbolTable(
+    if (_layout.hasDynamicRelocationTable())
+      _layout.getDynamicRelocationTable()->setSymbolTable(
+          _dynamicSymbolTable.get());
+    if (_layout.hasPLTRelocationTable())
+      _layout.getPLTRelocationTable()->setSymbolTable(
           _dynamicSymbolTable.get());
   }
+}
 
-  // give a chance for the target to add sections
-  _targetHandler.createDefaultSections();
+/// \brief create dynamic table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
+    OutputELFWriter<ELFT>::createDynamicTable() {
+  return LLD_UNIQUE_BUMP_PTR(
+      DynamicTable<ELFT>)(new (_alloc) DynamicTable<ELFT>(
+      this->_context, _layout, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
+}
+
+/// \brief create dynamic symbol table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+    OutputELFWriter<ELFT>::createDynamicSymbolTable() {
+  return LLD_UNIQUE_BUMP_PTR(
+      DynamicSymbolTable<ELFT>)(new (_alloc) DynamicSymbolTable<ELFT>(
+      this->_context, _layout, ".dynsym",
+      DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
 }
 
 template <class ELFT>
@@ -334,7 +357,7 @@ error_code OutputELFWriter<ELFT>::buildO
   createDefaultSections();
 
   // Set the Layout
-  _layout->assignSectionsToSegments();
+  _layout.assignSectionsToSegments();
 
   // Create the dynamic table entries
   if (_context.isDynamic()) {
@@ -344,10 +367,10 @@ error_code OutputELFWriter<ELFT>::buildO
 
   // Call the preFlight callbacks to modify the sections and the atoms
   // contained in them, in anyway the targets may want
-  _layout->doPreFlight();
+  _layout.doPreFlight();
 
-  _layout->assignFileOffsets();
-  _layout->assignVirtualAddress();
+  _layout.assignFileOffsets();
+  _layout.assignVirtualAddress();
 
   // Finalize the default value of symbols that the linker adds
   finalizeDefaultAtomValues();
@@ -359,7 +382,7 @@ error_code OutputELFWriter<ELFT>::buildO
   buildStaticSymbolTable(file);
 
   // Finalize the layout by calling the finalize() functions
-  _layout->finalize();
+  _layout.finalize();
 
   // build Section Header table
   buildSectionHeaderTable();
@@ -393,7 +416,7 @@ template <class ELFT> error_code OutputE
   _elfHeader->e_shnum(_shdrtab->numHeaders());
   _elfHeader->e_shstrndx(_shstrtab->ordinal());
   uint64_t virtualAddr = 0;
-  _layout->findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
+  _layout.findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
   _elfHeader->e_entry(virtualAddr);
 
   return error_code::success();
@@ -420,11 +443,11 @@ error_code OutputELFWriter<ELFT>::writeO
   // HACK: We have to write out the header and program header here even though
   // they are a member of a segment because only sections are written in the
   // following loop.
-  _elfHeader->write(this, *buffer);
-  _programHeader->write(this, *buffer);
+  _elfHeader->write(this, _layout, *buffer);
+  _programHeader->write(this, _layout, *buffer);
 
-  for (auto section : _layout->sections())
-    section->write(this, *buffer);
+  for (auto section : _layout.sections())
+    section->write(this, _layout, *buffer);
   writeTask.end();
 
   ScopedTask commitTask(getDefaultDomain(), "ELF Writer commit to disk");

Added: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,38 @@
+//===- lib/ReaderWriter/ELF/PPCELFFile.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_PPC_ELF_FILE_H
+#define LLD_READER_WRITER_ELF_PPC_ELF_FILE_H
+
+#include "ELFReader.h"
+
+namespace lld {
+namespace elf {
+
+class PPCLinkingContext;
+
+template <class ELFT> class PPCELFFile : public ELFFile<ELFT> {
+public:
+  PPCELFFile(StringRef name) : ELFFile<ELFT>(name) {}
+
+  PPCELFFile(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
+             TargetHandlerBase *handler, error_code &ec)
+      : ELFFile<ELFT>(std::move(mb), atomizeStrings, handler, ec) {}
+};
+
+template <class ELFT> class PPCDynamicFile : public DynamicFile<ELFT> {
+public:
+  PPCDynamicFile(const PPCLinkingContext &context, StringRef name)
+      : DynamicFile<ELFT>(context, name) {}
+};
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_PPC_ELF_FILE_H

Added: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,81 @@
+//===- lib/ReaderWriter/ELF/PPCELFReader.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_PPC_ELF_READER_H
+#define LLD_READER_WRITER_PPC_ELF_READER_H
+
+#include "ELFReader.h"
+#include "PPCELFFile.h"
+
+namespace lld {
+namespace elf {
+
+struct PPCDynamicFileCreateELFTraits {
+  typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
+
+  template <class ELFT>
+  static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+                            bool useUndefines) {
+    return lld::elf::PPCDynamicFile<ELFT>::create(std::move(mb), useUndefines);
+  }
+};
+
+struct PPCELFFileCreateELFTraits {
+  typedef llvm::ErrorOr<std::unique_ptr<lld::File>> result_type;
+
+  template <class ELFT>
+  static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+                            bool atomizeStrings) {
+    return lld::elf::PPCELFFile<ELFT>::create(std::move(mb), atomizeStrings);
+  }
+};
+
+class PPCELFObjectReader : public ELFObjectReader {
+public:
+  PPCELFObjectReader(bool atomizeStrings) : ELFObjectReader(atomizeStrings) {}
+
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File>> &result) const {
+    error_code ec;
+    std::size_t maxAlignment =
+        1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
+    auto f = createELF<PPCELFFileCreateELFTraits>(
+        llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
+        _atomizeStrings);
+    if (!f)
+      return f;
+    result.push_back(std::move(*f));
+    return error_code::success();
+  }
+};
+
+class PPCELFDSOReader : public ELFDSOReader {
+public:
+  PPCELFDSOReader(bool useUndefines) : ELFDSOReader(useUndefines) {}
+
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File>> &result) const {
+    std::size_t maxAlignment =
+        1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
+    auto f = createELF<PPCDynamicFileCreateELFTraits>(
+        llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
+        _useUndefines);
+    if (!f)
+      return f;
+    result.push_back(std::move(*f));
+    return error_code::success();
+  }
+};
+
+} // namespace elf
+} // namespace lld
+
+#endif // LLD_READER_WRITER_ELF_READER_H

Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -63,15 +63,32 @@ error_code PPCTargetRelocationHandler::a
   return error_code::success();
 }
 
-PPCTargetHandler::PPCTargetHandler(PPCLinkingContext &targetInfo)
-    : DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
-      _targetLayout(targetInfo) {}
+PPCTargetHandler::PPCTargetHandler(PPCLinkingContext &context)
+    : DefaultTargetHandler(context), _ppcLinkingContext(context),
+      _ppcTargetLayout(new PPCTargetLayout<PPCELFType>(context)),
+      _ppcRelocationHandler(
+          new PPCTargetRelocationHandler(context, *_ppcTargetLayout.get())) {}
 
 void PPCTargetHandler::registerRelocationNames(Registry &registry) {
   registry.addKindTable(Reference::KindNamespace::ELF,
                         Reference::KindArch::PowerPC, kindStrings);
 }
 
+std::unique_ptr<Writer> PPCTargetHandler::getWriter() {
+  switch (_ppcLinkingContext.getOutputELFType()) {
+  case llvm::ELF::ET_EXEC:
+    return std::unique_ptr<Writer>(new elf::ExecutableWriter<PPCELFType>(
+        _ppcLinkingContext, *_ppcTargetLayout.get()));
+  case llvm::ELF::ET_DYN:
+    return std::unique_ptr<Writer>(new elf::DynamicLibraryWriter<PPCELFType>(
+        _ppcLinkingContext, *_ppcTargetLayout.get()));
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
+  }
+}
+
 const Registry::KindStrings PPCTargetHandler::kindStrings[] = {
   LLD_KIND_STRING_ENTRY(R_PPC_NONE),
   LLD_KIND_STRING_ENTRY(R_PPC_ADDR32),

Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -18,35 +18,49 @@ namespace elf {
 typedef llvm::object::ELFType<llvm::support::big, 2, false> PPCELFType;
 class PPCLinkingContext;
 
+template <class ELFT> class PPCTargetLayout : public TargetLayout<ELFT> {
+public:
+  PPCTargetLayout(PPCLinkingContext &context) : TargetLayout<ELFT>(context) {}
+};
+
 class PPCTargetRelocationHandler LLVM_FINAL
     : public TargetRelocationHandler<PPCELFType> {
 public:
-  PPCTargetRelocationHandler(const PPCLinkingContext &context) {}
+  PPCTargetRelocationHandler(PPCLinkingContext &context,
+                             PPCTargetLayout<PPCELFType> &layout)
+      : _ppcContext(context), _ppcTargetLayout(layout) {}
 
   virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
                                      const lld::AtomLayout &,
                                      const Reference &) const;
 
+protected:
+  PPCLinkingContext &_ppcContext;
+  PPCTargetLayout<PPCELFType> &_ppcTargetLayout;
 };
 
 class PPCTargetHandler LLVM_FINAL
     : public DefaultTargetHandler<PPCELFType> {
 public:
-  PPCTargetHandler(PPCLinkingContext &targetInfo);
+  PPCTargetHandler(PPCLinkingContext &context);
 
-  virtual void registerRelocationNames(Registry &registry);
+  virtual PPCTargetLayout<PPCELFType> &getTargetLayout() {
+    return *(_ppcTargetLayout.get());
+  }
 
-  virtual TargetLayout<PPCELFType> &targetLayout() { return _targetLayout; }
+  virtual void registerRelocationNames(Registry &registry);
 
   virtual const PPCTargetRelocationHandler &getRelocationHandler() const {
-    return _relocationHandler;
+    return *(_ppcRelocationHandler.get());
   }
 
+  virtual std::unique_ptr<Writer> getWriter();
+
 private:
   static const Registry::KindStrings kindStrings[];
-
-  PPCTargetRelocationHandler _relocationHandler;
-  TargetLayout<PPCELFType> _targetLayout;
+  PPCLinkingContext &_ppcLinkingContext;
+  std::unique_ptr<PPCTargetLayout<PPCELFType>> _ppcTargetLayout;
+  std::unique_ptr<PPCTargetRelocationHandler> _ppcRelocationHandler;
 };
 } // end namespace elf
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Sun Jan 26 19:21:02 2014
@@ -234,7 +234,8 @@ public:
 
   range<atom_iter> atoms() { return _atoms; }
 
-  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                     llvm::FileOutputBuffer &buffer);
 
   static bool classof(const Chunk<ELFT> *c) {
     return c->kind() == Chunk<ELFT>::Kind::AtomSection;
@@ -359,7 +360,7 @@ template <class ELFT> StringRef Section<
 
 /// \brief Write the section and the atom contents to the buffer
 template <class ELFT>
-void AtomSection<ELFT>::write(ELFWriter *writer,
+void AtomSection<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
                               llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   parallel_for_each(_atoms.begin(), _atoms.end(), [&](lld::AtomLayout * ai) {
@@ -524,7 +525,8 @@ public:
 
   uint64_t addString(StringRef symname);
 
-  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                     llvm::FileOutputBuffer &buffer);
 
   inline void setNumEntries(int64_t numEntries) {
     _stringMap.resize(numEntries);
@@ -583,7 +585,7 @@ template <class ELFT> uint64_t StringTab
 }
 
 template <class ELFT>
-void StringTable<ELFT>::write(ELFWriter *writer,
+void StringTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &,
                               llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   uint8_t *dest = chunkBuffer + this->fileOffset();
@@ -649,7 +651,8 @@ public:
 
   virtual void finalize(bool sort = true);
 
-  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                     llvm::FileOutputBuffer &buffer);
 
   void setStringSection(StringTable<ELFT> *s) { _stringSection = s; }
 
@@ -842,7 +845,7 @@ template <class ELFT> void SymbolTable<E
 }
 
 template <class ELFT>
-void SymbolTable<ELFT>::write(ELFWriter *writer,
+void SymbolTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &,
                               llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   uint8_t *dest = chunkBuffer + this->fileOffset();
@@ -856,9 +859,10 @@ template <class ELFT> class HashSection;
 
 template <class ELFT> class DynamicSymbolTable : public SymbolTable<ELFT> {
 public:
-  DynamicSymbolTable(const ELFLinkingContext &context, const char *str,
-                     int32_t order)
-      : SymbolTable<ELFT>(context, str, order), _hashTable(nullptr) {
+  DynamicSymbolTable(const ELFLinkingContext &context,
+                     TargetLayout<ELFT> &layout, const char *str, int32_t order)
+      : SymbolTable<ELFT>(context, str, order), _hashTable(nullptr),
+        _layout(layout) {
     this->_type = SHT_DYNSYM;
     this->_flags = SHF_ALLOC;
     this->_msize = this->_fsize;
@@ -894,8 +898,9 @@ public:
     SymbolTable<ELFT>::finalize(false);
   }
 
-private:
+protected:
   HashSection<ELFT> *_hashTable;
+  TargetLayout<ELFT> &_layout;
 };
 
 template <class ELFT> class RelocationTable : public Section<ELFT> {
@@ -951,8 +956,10 @@ public:
       this->_parent->setLink(this->_link);
   }
 
-  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
-    uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                     llvm::FileOutputBuffer &buffer) {
+    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,
@@ -1007,8 +1014,9 @@ public:
   typedef llvm::object::Elf_Dyn_Impl<ELFT> Elf_Dyn;
   typedef std::vector<Elf_Dyn> EntriesT;
 
-  DynamicTable(const ELFLinkingContext &context, StringRef str, int32_t order)
-      : Section<ELFT>(context, str) {
+  DynamicTable(const ELFLinkingContext &context, TargetLayout<ELFT> &layout,
+               StringRef str, int32_t order)
+      : Section<ELFT>(context, str), _layout(layout) {
     this->setOrder(order);
     this->_entSize = sizeof(Elf_Dyn);
     this->_align2 = llvm::alignOf<Elf_Dyn>();
@@ -1017,7 +1025,6 @@ public:
     this->_msize = sizeof(Elf_Dyn);
     this->_type = SHT_DYNAMIC;
     this->_flags = SHF_ALLOC;
-    _layout = &context.getTargetHandler<ELFT>().targetLayout();
   }
 
   range<typename EntriesT::iterator> entries() { return _entries; }
@@ -1030,7 +1037,8 @@ public:
     return _entries.size() - 1;
   }
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+  void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+             llvm::FileOutputBuffer &buffer) {
     uint8_t *chunkBuffer = buffer.getBufferStart();
     uint8_t *dest = chunkBuffer + this->fileOffset();
     // Add the null entry.
@@ -1061,7 +1069,7 @@ public:
     _dt_fini_array = addEntry(dyn);
     dyn.d_tag = DT_FINI_ARRAYSZ;
     _dt_fini_arraysz = addEntry(dyn);
-    if (_layout->hasDynamicRelocationTable()) {
+    if (_layout.hasDynamicRelocationTable()) {
       dyn.d_tag = isRela ? DT_RELA : DT_REL;
       _dt_rela = addEntry(dyn);
       dyn.d_tag = isRela ? DT_RELASZ : DT_RELSZ;
@@ -1069,7 +1077,7 @@ public:
       dyn.d_tag = isRela ? DT_RELAENT : DT_RELENT;
       _dt_relaent = addEntry(dyn);
     }
-    if (_layout->hasPLTRelocationTable()) {
+    if (_layout.hasPLTRelocationTable()) {
       dyn.d_tag = DT_PLTRELSZ;
       _dt_pltrelsz = addEntry(dyn);
       dyn.d_tag = DT_PLTGOT;
@@ -1111,30 +1119,28 @@ public:
     _entries[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr();
     _entries[_dt_strsz].d_un.d_val = dynamicStringTable->memSize();
     _entries[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize();
-    auto finiArray = _layout->findOutputSection(".fini_array");
+    auto finiArray = _layout.findOutputSection(".fini_array");
     if (finiArray) {
       _entries[_dt_fini_array].d_un.d_val = finiArray->virtualAddr();
       _entries[_dt_fini_arraysz].d_un.d_val = finiArray->memSize();
     }
-    if (_layout->hasDynamicRelocationTable()) {
-      auto relaTbl = _layout->getDynamicRelocationTable();
+    if (_layout.hasDynamicRelocationTable()) {
+      auto relaTbl = _layout.getDynamicRelocationTable();
       _entries[_dt_rela].d_un.d_val = relaTbl->virtualAddr();
       _entries[_dt_relasz].d_un.d_val = relaTbl->memSize();
       _entries[_dt_relaent].d_un.d_val = relaTbl->getEntSize();
     }
-    if (_layout->hasPLTRelocationTable()) {
-      auto relaTbl = _layout->getPLTRelocationTable();
+    if (_layout.hasPLTRelocationTable()) {
+      auto relaTbl = _layout.getPLTRelocationTable();
       _entries[_dt_jmprel].d_un.d_val = relaTbl->virtualAddr();
       _entries[_dt_pltrelsz].d_un.d_val = relaTbl->memSize();
-      auto gotplt = _layout->findOutputSection(".got.plt");
+      auto gotplt = _layout.findOutputSection(".got.plt");
       _entries[_dt_pltgot].d_un.d_val = gotplt->virtualAddr();
     }
   }
 
 protected:
   EntriesT _entries;
-
-private:
   std::size_t _dt_hash;
   std::size_t _dt_strtab;
   std::size_t _dt_symtab;
@@ -1149,7 +1155,7 @@ private:
   std::size_t _dt_jmprel;
   std::size_t _dt_fini_array;
   std::size_t _dt_fini_arraysz;
-  TargetLayout<ELFT> *_layout;
+  TargetLayout<ELFT> &_layout;
   DynamicSymbolTable<ELFT> *_dynamicSymbolTable;
   HashSection<ELFT> *_hashTable;
 };
@@ -1168,7 +1174,8 @@ public:
     this->_flags = SHF_ALLOC;
   }
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+  void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+             llvm::FileOutputBuffer &buffer) {
     uint8_t *chunkBuffer = buffer.getBufferStart();
     uint8_t *dest = chunkBuffer + this->fileOffset();
     std::memcpy(dest, _interp.data(), _interp.size());
@@ -1280,7 +1287,8 @@ public:
       this->_parent->setLink(this->_link);
   }
 
-  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                     llvm::FileOutputBuffer &buffer) {
     uint8_t *chunkBuffer = buffer.getBufferStart();
     uint8_t *dest = chunkBuffer + this->fileOffset();
     uint32_t bucketChainCounts[2];
@@ -1311,8 +1319,9 @@ private:
 
 template <class ELFT> class EHFrameHeader : public Section<ELFT> {
 public:
-  EHFrameHeader(const ELFLinkingContext &context, StringRef name, int32_t order)
-      : Section<ELFT>(context, name) {
+  EHFrameHeader(const ELFLinkingContext &context, StringRef name,
+                TargetLayout<ELFT> &layout, int32_t order)
+      : Section<ELFT>(context, name), _layout(layout) {
     this->setOrder(order);
     this->_entSize = 0;
     this->_type = SHT_PROGBITS;
@@ -1332,13 +1341,11 @@ public:
   }
 
   virtual void finalize() LLVM_OVERRIDE {
-    MergedSections<ELFT> *s = this->_context.template getTargetHandler<ELFT>()
-                                  .targetLayout()
-                                  .findOutputSection(".eh_frame");
+    MergedSections<ELFT> *s = _layout.findOutputSection(".eh_frame");
     _ehFrameAddr = s ? s->virtualAddr() : 0;
   }
 
-  virtual void write(ELFWriter *writer,
+  virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
                      llvm::FileOutputBuffer &buffer) LLVM_OVERRIDE {
     uint8_t *chunkBuffer = buffer.getBufferStart();
     uint8_t *dest = chunkBuffer + this->fileOffset();
@@ -1353,6 +1360,7 @@ public:
 
 private:
   uint64_t _ehFrameAddr;
+  TargetLayout<ELFT> &_layout;
 };
 } // end namespace elf
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Sun Jan 26 19:21:02 2014
@@ -159,7 +159,8 @@ public:
   void assignVirtualAddress(uint64_t &addr);
 
   // Write the Segment
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+             llvm::FileOutputBuffer &buffer);
 
   int64_t flags() const;
 
@@ -582,10 +583,11 @@ template <class ELFT> void Segment<ELFT>
 
 // Write the Segment
 template <class ELFT>
-void Segment<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+void Segment<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+                          llvm::FileOutputBuffer &buffer) {
   for (auto slice : slices())
     for (auto section : slice->sections())
-      section->write(writer, buffer);
+      section->write(writer, layout, buffer);
 }
 
 template<class ELFT>

Modified: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h Sun Jan 26 19:21:02 2014
@@ -42,63 +42,38 @@ template <class ELFT> class TargetLayout
 
 template <class ELFT> class TargetRelocationHandler {
 public:
-  virtual error_code
-  applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
-                  const lld::AtomLayout &, const Reference &) const = 0;
+  virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
+                                     const lld::AtomLayout &,
+                                     const Reference &) const = 0;
 
   virtual ~TargetRelocationHandler() {}
 };
 
-/// \brief An interface to override functions that are provided by the
-/// the default ELF Layout
+/// \brief TargetHandler contains all the information responsible to handle a
+/// a particular target on ELF. A target might wish to override implementation
+/// of creating atoms and how the atoms are written to the output file.
 template <class ELFT> class TargetHandler : public TargetHandlerBase {
 
 public:
+  /// Constructor
   TargetHandler(ELFLinkingContext &targetInfo) : _context(targetInfo) {}
 
-  /// If the target overrides ELF header information, this API would
-  /// return true, so that the target can set all fields specific to
-  /// that target
-  virtual bool doesOverrideELFHeader() = 0;
-
-  /// Set the ELF Header information
-  virtual void setELFHeader(ELFHeader<ELFT> *elfHeader) = 0;
-
-  /// TargetLayout
-  virtual TargetLayout<ELFT> &targetLayout() = 0;
+  /// The layout determined completely by the Target.
+  virtual TargetLayout<ELFT> &getTargetLayout() = 0;
 
+  /// Determine how relocations need to be applied.
   virtual const TargetRelocationHandler<ELFT> &getRelocationHandler() const = 0;
 
-  /// Create a set of Default target sections that a target might needj
-  virtual void createDefaultSections() = 0;
-
-  /// \brief Add a section to the current Layout
-  virtual void addSection(Section<ELFT> *section) = 0;
-
-  /// \brief add new symbol file
-  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) = 0;
-
-  /// \brief Finalize the symbol values
-  virtual void finalizeSymbolValues() = 0;
-
-  /// \brief allocate Commons, some architectures may move small common
-  /// symbols over to small data, this would also be used
-  virtual void allocateCommons() = 0;
-
-  /// \brief create dynamic table
-  virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() = 0;
-
-  /// \brief create dynamic symbol table
-  virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
-  createDynamicSymbolTable() = 0;
-
+  /// How does the target deal with reading input files.
   virtual std::unique_ptr<Reader> getObjReader(bool) = 0;
 
+  /// How does the target deal with reading dynamic libraries.
   virtual std::unique_ptr<Reader> getDSOReader(bool) = 0;
 
+  /// How does the target deal with writing ELF output.
   virtual std::unique_ptr<Writer> getWriter() = 0;
 
-protected:
+private:
   ELFLinkingContext &_context;
 };
 } // end namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -31,6 +31,21 @@ static int relocPC32(uint8_t *location,
   return 0;
 }
 
+std::unique_ptr<Writer> X86TargetHandler::getWriter() {
+  switch (_x86LinkingContext.getOutputELFType()) {
+  case llvm::ELF::ET_EXEC:
+    return std::unique_ptr<Writer>(new elf::ExecutableWriter<X86ELFType>(
+        _x86LinkingContext, *_x86TargetLayout.get()));
+  case llvm::ELF::ET_DYN:
+    return std::unique_ptr<Writer>(new elf::DynamicLibraryWriter<X86ELFType>(
+        _x86LinkingContext, *_x86TargetLayout.get()));
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
+  }
+}
+
 const Registry::KindStrings X86TargetHandler::kindStrings[] = {
   LLD_KIND_STRING_ENTRY(R_386_NONE),
   LLD_KIND_STRING_ENTRY(R_386_32),
@@ -111,6 +126,8 @@ error_code X86TargetRelocationHandler::a
   return error_code::success();
 }
 
-X86TargetHandler::X86TargetHandler(X86LinkingContext &targetInfo)
-    : DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
-      _targetLayout(targetInfo) {}
+X86TargetHandler::X86TargetHandler(X86LinkingContext &context)
+    : DefaultTargetHandler(context), _x86LinkingContext(context),
+      _x86TargetLayout(new X86TargetLayout<X86ELFType>(context)),
+      _x86RelocationHandler(
+          new X86TargetRelocationHandler(context, *_x86TargetLayout.get())) {}

Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h Sun Jan 26 19:21:02 2014
@@ -21,16 +21,27 @@ namespace elf {
 typedef llvm::object::ELFType<llvm::support::little, 2, false> X86ELFType;
 class X86LinkingContext;
 
+template <class ELFT> class X86TargetLayout : public TargetLayout<ELFT> {
+public:
+  X86TargetLayout(X86LinkingContext &context) : TargetLayout<ELFT>(context) {}
+};
+
 class X86TargetRelocationHandler LLVM_FINAL
     : public TargetRelocationHandler<X86ELFType> {
 public:
-  X86TargetRelocationHandler(const X86LinkingContext &context) {}
+  X86TargetRelocationHandler(X86LinkingContext &context,
+                             X86TargetLayout<X86ELFType> &layout)
+      : _x86Context(context), _x86TargetLayout(layout) {}
 
   virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
                                      const lld::AtomLayout &,
                                      const Reference &) const;
 
   static const Registry::KindStrings kindStrings[];
+
+protected:
+  X86LinkingContext &_x86Context;
+  X86TargetLayout<X86ELFType> &_x86TargetLayout;
 };
 
 class X86TargetHandler LLVM_FINAL
@@ -38,19 +49,23 @@ class X86TargetHandler LLVM_FINAL
 public:
   X86TargetHandler(X86LinkingContext &context);
 
-  virtual void registerRelocationNames(Registry &registry);
+  virtual X86TargetLayout<X86ELFType> &getTargetLayout() {
+    return *(_x86TargetLayout.get());
+  }
 
-  virtual TargetLayout<X86ELFType> &targetLayout() { return _targetLayout; }
+  virtual void registerRelocationNames(Registry &registry);
 
   virtual const X86TargetRelocationHandler &getRelocationHandler() const {
-    return _relocationHandler;
+    return *(_x86RelocationHandler.get());
   }
 
-private:
-  static const Registry::KindStrings kindStrings[];
+  virtual std::unique_ptr<Writer> getWriter();
 
-  X86TargetRelocationHandler _relocationHandler;
-  TargetLayout<X86ELFType> _targetLayout;
+protected:
+  static const Registry::KindStrings kindStrings[];
+  X86LinkingContext &_x86LinkingContext;
+  std::unique_ptr<X86TargetLayout<X86ELFType>> _x86TargetLayout;
+  std::unique_ptr<X86TargetRelocationHandler> _x86RelocationHandler;
 };
 } // end namespace elf
 } // end namespace lld

Added: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,70 @@
+//===- lib/ReaderWriter/ELF/X86/X86_64DynamicLibraryWriter.h
+//-----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_64_DYNAMIC_LIBRARY_WRITER_H
+#define X86_64_DYNAMIC_LIBRARY_WRITER_H
+
+#include "DynamicLibraryWriter.h"
+#include "X86_64LinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+class X86_64DynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
+public:
+  X86_64DynamicLibraryWriter(X86_64LinkingContext &context,
+                             X86_64TargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+  virtual void finalizeDefaultAtomValues() {
+    return DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+  }
+
+  virtual void addDefaultAtoms() {
+    return DynamicLibraryWriter<ELFT>::addDefaultAtoms();
+  }
+
+private:
+  class GOTFile : public SimpleFile {
+  public:
+    GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
+    llvm::BumpPtrAllocator _alloc;
+  };
+
+  std::unique_ptr<GOTFile> _gotFile;
+  X86_64LinkingContext &_context;
+  X86_64TargetLayout<ELFT> &_x86_64Layout;
+};
+
+template <class ELFT>
+X86_64DynamicLibraryWriter<ELFT>::X86_64DynamicLibraryWriter(
+    X86_64LinkingContext &context, X86_64TargetLayout<ELFT> &layout)
+    : DynamicLibraryWriter<ELFT>(context, layout),
+      _gotFile(new GOTFile(context)), _context(context), _x86_64Layout(layout) {
+}
+
+template <class ELFT>
+bool X86_64DynamicLibraryWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+  _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
+  _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
+  _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
+  result.push_back(std::move(_gotFile));
+  return true;
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif

Added: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,70 @@
+//===- lib/ReaderWriter/ELF/X86/X86_64ExecutableWriter.h
+//-----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_64_EXECUTABLE_WRITER_H
+#define X86_64_EXECUTABLE_WRITER_H
+
+#include "ExecutableWriter.h"
+#include "X86_64LinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+class X86_64ExecutableWriter : public ExecutableWriter<ELFT> {
+public:
+  X86_64ExecutableWriter(X86_64LinkingContext &context,
+                         X86_64TargetLayout<ELFT> &layout);
+
+protected:
+  // Add any runtime files and their atoms to the output
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+  virtual void finalizeDefaultAtomValues() {
+    return ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+  }
+
+  virtual void addDefaultAtoms() {
+    return ExecutableWriter<ELFT>::addDefaultAtoms();
+  }
+
+private:
+  class GOTFile : public SimpleFile {
+  public:
+    GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
+    llvm::BumpPtrAllocator _alloc;
+  };
+
+  std::unique_ptr<GOTFile> _gotFile;
+  X86_64LinkingContext &_context;
+  X86_64TargetLayout<ELFT> &_x86_64Layout;
+};
+
+template <class ELFT>
+X86_64ExecutableWriter<ELFT>::X86_64ExecutableWriter(
+    X86_64LinkingContext &context, X86_64TargetLayout<ELFT> &layout)
+    : ExecutableWriter<ELFT>(context, layout), _gotFile(new GOTFile(context)),
+      _context(context), _x86_64Layout(layout) {}
+
+template <class ELFT>
+bool X86_64ExecutableWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File>> &result) {
+  ExecutableWriter<ELFT>::createImplicitFiles(result);
+  _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
+  _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
+  if (_context.isDynamic())
+    _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
+  result.push_back(std::move(_gotFile));
+  return true;
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp Sun Jan 26 19:21:02 2014
@@ -90,8 +90,7 @@ error_code X86_64TargetRelocationHandler
   case R_X86_64_TPOFF64:
   case R_X86_64_DTPOFF32:
   case R_X86_64_TPOFF32: {
-    _tlsSize =
-        _context.getTargetHandler<X86_64ELFType>().targetLayout().getTLSSize();
+    _tlsSize = _x86_64Layout.getTLSSize();
     if (ref.kindValue() == R_X86_64_TPOFF32 ||
         ref.kindValue() == R_X86_64_DTPOFF32) {
       int32_t result = (int32_t)(targetVAddress - _tlsSize);
@@ -115,8 +114,8 @@ error_code X86_64TargetRelocationHandler
     for (const Reference *r : *target) {
       if (r->kindValue() == R_X86_64_JUMP_SLOT) {
         uint32_t index;
-        if (!_context.getTargetHandler<X86_64ELFType>().targetLayout()
-                .getPLTRelocationTable()->getRelocationIndex(*r, index))
+        if (!_x86_64Layout.getPLTRelocationTable()->getRelocationIndex(*r,
+                                                                       index))
           llvm_unreachable("Relocation doesn't exist");
         reloc32(location, 0, index, 0);
         break;

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h Sun Jan 26 19:21:02 2014
@@ -8,8 +8,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_RELOCATION_HANDLER_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_RELOCATION_HANDLER_H
+#ifndef X86_64_RELOCATION_HANDLER_H
+#define X86_64_RELOCATION_HANDLER_H
 
 #include "X86_64TargetHandler.h"
 
@@ -18,11 +18,14 @@ namespace elf {
 typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
 class X86_64LinkingContext;
 
+template <class ELFT> class X86_64TargetLayout;
+
 class X86_64TargetRelocationHandler LLVM_FINAL
     : public TargetRelocationHandler<X86_64ELFType> {
 public:
-  X86_64TargetRelocationHandler(const X86_64LinkingContext &context)
-      : _tlsSize(0), _context(context) {}
+  X86_64TargetRelocationHandler(const X86_64LinkingContext &context,
+                                X86_64TargetLayout<X86_64ELFType> &layout)
+      : _tlsSize(0), _context(context), _x86_64Layout(layout) {}
 
   virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
                                      const lld::AtomLayout &,
@@ -35,10 +38,11 @@ public:
 private:
   // Cached size of the TLS segment.
   mutable uint64_t _tlsSize;
-  const X86_64LinkingContext &_context;
+  const X86_64LinkingContext &_context LLVM_ATTRIBUTE_UNUSED;
+  X86_64TargetLayout<X86_64ELFType> &_x86_64Layout;
 };
 
 } // end namespace elf
 } // end namespace lld
 
-#endif
+#endif // X86_64_RELOCATION_HANDLER_H

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "Atoms.h"
+#include "X86_64ExecutableWriter.h"
+#include "X86_64DynamicLibraryWriter.h"
 #include "X86_64TargetHandler.h"
 #include "X86_64LinkingContext.h"
 
@@ -15,24 +17,32 @@ using namespace lld;
 using namespace elf;
 
 X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &context)
-    : DefaultTargetHandler(context), _gotFile(new GOTFile(context)),
-      _relocationHandler(context), _targetLayout(context) {}
-
-bool X86_64TargetHandler::createImplicitFiles(
-    std::vector<std::unique_ptr<File> > &result) {
-  _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
-  _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
-  if (_context.isDynamic())
-    _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
-  result.push_back(std::move(_gotFile));
-  return true;
-}
+    : DefaultTargetHandler(context), _context(context),
+      _x86_64TargetLayout(new X86_64TargetLayout<X86_64ELFType>(context)),
+      _x86_64RelocationHandler(new X86_64TargetRelocationHandler(
+          context, *_x86_64TargetLayout.get())) {}
 
 void X86_64TargetHandler::registerRelocationNames(Registry &registry) {
   registry.addKindTable(Reference::KindNamespace::ELF,
                         Reference::KindArch::x86_64, kindStrings);
 }
 
+std::unique_ptr<Writer> X86_64TargetHandler::getWriter() {
+  switch (this->_context.getOutputELFType()) {
+  case llvm::ELF::ET_EXEC:
+    return std::unique_ptr<Writer>(new X86_64ExecutableWriter<X86_64ELFType>(
+        _context, *_x86_64TargetLayout.get()));
+  case llvm::ELF::ET_DYN:
+    return std::unique_ptr<Writer>(
+        new X86_64DynamicLibraryWriter<X86_64ELFType>(
+            _context, *_x86_64TargetLayout.get()));
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
+  }
+}
+
 const Registry::KindStrings X86_64TargetHandler::kindStrings[] = {
   LLD_KIND_STRING_ENTRY(R_X86_64_NONE),
   LLD_KIND_STRING_ENTRY(R_X86_64_64),

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h Sun Jan 26 19:21:02 2014
@@ -22,35 +22,36 @@ namespace elf {
 typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
 class X86_64LinkingContext;
 
+template <class ELFT> class X86_64TargetLayout : public TargetLayout<ELFT> {
+public:
+  X86_64TargetLayout(X86_64LinkingContext &context)
+      : TargetLayout<ELFT>(context) {}
+};
+
 class X86_64TargetHandler LLVM_FINAL
     : public DefaultTargetHandler<X86_64ELFType> {
 public:
-  X86_64TargetHandler(X86_64LinkingContext &targetInfo);
-
-  virtual void registerRelocationNames(Registry &registry);
+  X86_64TargetHandler(X86_64LinkingContext &context);
 
-  virtual TargetLayout<X86_64ELFType> &targetLayout() {
-    return _targetLayout;
+  virtual X86_64TargetLayout<X86_64ELFType> &getTargetLayout() {
+    return *(_x86_64TargetLayout.get());
   }
 
+  virtual void registerRelocationNames(Registry &registry);
+
   virtual const X86_64TargetRelocationHandler &getRelocationHandler() const {
-    return _relocationHandler;
+    return *(_x86_64RelocationHandler.get());
   }
 
-  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
+  virtual std::unique_ptr<Writer> getWriter();
 
 private:
-  class GOTFile : public SimpleFile {
-  public:
-    GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
-    llvm::BumpPtrAllocator _alloc;
-  };
-
   static const Registry::KindStrings kindStrings[];
-  std::unique_ptr<GOTFile> _gotFile;
-  X86_64TargetRelocationHandler _relocationHandler;
-  TargetLayout<X86_64ELFType> _targetLayout;
+  X86_64LinkingContext &_context;
+  std::unique_ptr<X86_64TargetLayout<X86_64ELFType>> _x86_64TargetLayout;
+  std::unique_ptr<X86_64TargetRelocationHandler> _x86_64RelocationHandler;
 };
+
 } // end namespace elf
 } // end namespace lld
 

Modified: lld/trunk/test/elf/Hexagon/dynlib-syms.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Hexagon/dynlib-syms.test?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/test/elf/Hexagon/dynlib-syms.test (original)
+++ lld/trunk/test/elf/Hexagon/dynlib-syms.test Sun Jan 26 19:21:02 2014
@@ -5,4 +5,3 @@ RUN: FileCheck -check-prefix=CHECKSYMS %
 
 CHECKSYMS: 0000028c A _DYNAMIC
 CHECKSYMS: 00001008 A _GLOBAL_OFFSET_TABLE_
-CHECKSYMS: 00002000 A _SDA_BASE_





More information about the llvm-commits mailing list