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

Rui Ueyama ruiu at google.com
Sun Jan 26 20:20:57 PST 2014


On Sun, Jan 26, 2014 at 6:30 PM, Shankar Easwaran
<shankare at codeaurora.org>wrote:

> 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.
>

If you find a bug in code, please fix it in an independent commit, so that
other people can easily understand what you are fixing.


> 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;
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140126/fc082f85/attachment.html>


More information about the llvm-commits mailing list