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

Shankar Easwaran shankare at codeaurora.org
Sun Jan 26 18:30:51 PST 2014


Hi Hal,

Thanks for your quick review!

Agree, the description of the commit should have contained more information.

Anyways, the details are :-

a) The individual ELF sub targets could override the basic functionality 
of ELF writing from the generic layer

What this amounts to is each ELF subtarget is in complete control of how 
the output ELF is written to by using the linker.

As for the test, there was a bug in the code, that I saw.

Will be more careful next time.

PS: The next few commits I plan are going to add more comments.

Thanks

Shankar Easwaran

On 1/26/2014 8:20 PM, Hal Finkel wrote:
> ----- Original Message -----
>> From: "Shankar Easwaran" <shankare at codeaurora.org>
>> To: llvm-commits at cs.uiuc.edu
>> Sent: Sunday, January 26, 2014 7:21:03 PM
>> Subject: [lld] r200177 - [ELF] Make changes to all the targets supported	currently
>>
>> 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
> "Make changes", seriously? ;) -- Can you please provide a more-verbose explanation of what you're doing.
>
>> X86_64,X86,PPC,Hexagon,Mips
>>
>> No change in functionality.
> One of the tests changed.
>
>   -Hal
>
>> 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_
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation




More information about the llvm-commits mailing list