[llvm-commits] [lld] r171526 - in /lld/trunk/lib/ReaderWriter/ELF: AtomsELF.h ReaderELF.cpp WriterELF.cpp

Michael Spencer bigcheesegs at gmail.com
Fri Jan 4 14:26:25 PST 2013


On Fri, Jan 4, 2013 at 1:24 PM, Chandler Carruth <chandlerc at google.com> wrote:
> Tests?

This is already tested by the archive tests. They only failed under
-fsanitize=undefined. They no longer fail with this patch.

- Michael Spencer

>
>
> On Fri, Jan 4, 2013 at 1:09 PM, Michael J. Spencer <bigcheesegs at gmail.com>
> wrote:
>>
>> Author: mspencer
>> Date: Fri Jan  4 15:09:21 2013
>> New Revision: 171526
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=171526&view=rev
>> Log:
>> [ELF] Handle misaligned ELF files properly.
>>
>> Modified:
>>     lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h
>>     lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp
>>     lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp
>>
>> Modified: lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h?rev=171526&r1=171525&r2=171526&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h (original)
>> +++ lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h Fri Jan  4 15:09:21 2013
>> @@ -8,12 +8,14 @@
>>  namespace lld {
>>  /// \brief Relocation References: Defined Atoms may contain references
>> that will
>>  /// need to be patched before the executable is written.
>> -template <llvm::support::endianness target_endianness, bool is64Bits>
>> +template<llvm::support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class ELFReference final : public Reference {
>>    typedef llvm::object::Elf_Rel_Impl
>> -                        <target_endianness, is64Bits, false> Elf_Rel;
>> +                        <target_endianness, max_align, is64Bits, false>
>> Elf_Rel;
>>    typedef llvm::object::Elf_Rel_Impl
>> -                        <target_endianness, is64Bits, true> Elf_Rela;
>> +                        <target_endianness, max_align, is64Bits, true>
>> Elf_Rela;
>>  public:
>>
>>    ELFReference(const Elf_Rela *rela, uint64_t offset, const Atom *target)
>> @@ -73,9 +75,12 @@
>>  /// \brief These atoms store symbols that are fixed to a particular
>> address.
>>  /// This atom has no content its address will be used by the writer to
>> fixup
>>  /// references that point to it.
>> -template<llvm::support::endianness target_endianness, bool is64Bits>
>> +template<llvm::support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class ELFAbsoluteAtom final : public AbsoluteAtom {
>> -  typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits>
>> Elf_Sym;
>> +  typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align,
>> is64Bits>
>> +    Elf_Sym;
>>
>>  public:
>>    ELFAbsoluteAtom(const File &file,
>> @@ -118,9 +123,12 @@
>>
>>  /// \brief ELFUndefinedAtom: These atoms store undefined symbols and are
>> place
>>  /// holders that will be replaced by defined atoms later in the linking
>> process.
>> -template<llvm::support::endianness target_endianness, bool is64Bits>
>> +template<llvm::support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class ELFUndefinedAtom final: public UndefinedAtom {
>> -  typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits>
>> Elf_Sym;
>> +  typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align,
>> is64Bits>
>> +    Elf_Sym;
>>
>>  public:
>>    ELFUndefinedAtom(const File &file,
>> @@ -157,10 +165,14 @@
>>
>>  /// \brief This atom stores defined symbols and will contain either data
>> or
>>  /// code.
>> -template<llvm::support::endianness target_endianness, bool is64Bits>
>> +template<llvm::support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class ELFDefinedAtom final: public DefinedAtom {
>> -  typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits>
>> Elf_Sym;
>> -  typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits>
>> Elf_Shdr;
>> +  typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align,
>> is64Bits>
>> +    Elf_Sym;
>> +  typedef llvm::object::Elf_Shdr_Impl<target_endianness, max_align,
>> is64Bits>
>> +    Elf_Shdr;
>>
>>  public:
>>    ELFDefinedAtom(const File &file,
>> @@ -171,8 +183,8 @@
>>                   llvm::ArrayRef<uint8_t> contentData,
>>                   unsigned int referenceStart,
>>                   unsigned int referenceEnd,
>> -                 std::vector<ELFReference
>> -                             <target_endianness, is64Bits> *>
>> &referenceList)
>> +                 std::vector<ELFReference<target_endianness,
>> +                                          max_align, is64Bits>*>
>> &referenceList)
>>
>>      : _owningFile(file)
>>      , _symbolName(symbolName)
>> @@ -236,7 +248,6 @@
>>    }
>>
>>    virtual ContentType contentType() const {
>> -
>>      ContentType ret = typeUnknown;
>>      uint64_t flags = _section->sh_flags;
>>
>> @@ -284,7 +295,7 @@
>>          || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
>>        return Alignment(llvm::Log2_64(_symbol->st_value));
>>      }
>> -    return Alignment(llvm::Log2_64(_section->sh_addralign),
>> +    return Alignment(llvm::Log2_64(_section->sh_addralign),
>>                       _symbol->st_value % _section->sh_addralign);
>>    }
>>
>> @@ -298,7 +309,7 @@
>>
>>    virtual llvm::StringRef customSectionName() const {
>>      if ((contentType() == typeZeroFill) ||
>> -        (_symbol->st_shndx == llvm::ELF::SHN_COMMON))
>> +        (_symbol->st_shndx == llvm::ELF::SHN_COMMON))
>>        return ".bss";
>>      return _sectionName;
>>    }
>> @@ -337,7 +348,7 @@
>>          return permR__;
>>
>>        default:
>> -        if (flags & llvm::ELF::SHF_WRITE)
>> +        if (flags & llvm::ELF::SHF_WRITE)
>>            return permRW_;
>>          return permR__;
>>        }
>> @@ -403,7 +414,8 @@
>>    uint64_t _ordinal;
>>    unsigned int _referenceStartIndex;
>>    unsigned int _referenceEndIndex;
>> -  std::vector<ELFReference<target_endianness, is64Bits> *>
>> &_referenceList;
>> +  std::vector<ELFReference<target_endianness, max_align, is64Bits>*> &
>> +    _referenceList;
>>  };
>>  } // namespace lld
>>  #endif
>>
>> Modified: lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp?rev=171526&r1=171525&r2=171526&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp (original)
>> +++ lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp Fri Jan  4 15:09:21 2013
>> @@ -41,37 +41,33 @@
>>  #include <vector>
>>
>>  using namespace lld;
>> -using llvm::object::Elf_Sym_Impl;
>>  using llvm::support::endianness;
>> +using namespace llvm::object;
>>
>>  namespace {
>>  // \brief Read a binary, find out based on the symbol table contents what
>> kind
>>  // of symbol it is and create corresponding atoms for it
>> -template<endianness target_endianness, bool is64Bits>
>> +template<endianness target_endianness, std::size_t max_align, bool
>> is64Bits>
>>  class FileELF: public File {
>> -  typedef llvm::object::Elf_Sym_Impl
>> -                        <target_endianness, is64Bits> Elf_Sym;
>> -  typedef llvm::object::Elf_Shdr_Impl
>> -                        <target_endianness, is64Bits> Elf_Shdr;
>> -  typedef llvm::object::Elf_Rel_Impl
>> -                        <target_endianness, is64Bits, false> Elf_Rel;
>> -  typedef llvm::object::Elf_Rel_Impl
>> -                        <target_endianness, is64Bits, true> Elf_Rela;
>> +  typedef Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;
>> +  typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;
>> +  typedef Elf_Rel_Impl<target_endianness, max_align, is64Bits, false>
>> Elf_Rel;
>> +  typedef Elf_Rel_Impl<target_endianness, max_align, is64Bits, true>
>> Elf_Rela;
>>
>>  public:
>>    FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)
>>      :  File(MB->getBufferIdentifier()) {
>> -    llvm::OwningPtr<llvm::object::Binary> binaryFile;
>> -    EC = llvm::object::createBinary(MB.release(), binaryFile);
>> +    llvm::OwningPtr<Binary> binaryFile;
>> +    EC = createBinary(MB.release(), binaryFile);
>>      if (EC)
>>        return;
>>
>>      // Point Obj to correct class and bitwidth ELF object
>> -
>> _objFile.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,
>> +    _objFile.reset(llvm::dyn_cast<ELFObjectFile<target_endianness,
>> max_align,
>>          is64Bits> >(binaryFile.get()));
>>
>>      if (!_objFile) {
>> -      EC =
>> make_error_code(llvm::object::object_error::invalid_file_type);
>> +      EC = make_error_code(object_error::invalid_file_type);
>>        return;
>>      }
>>
>> @@ -82,8 +78,8 @@
>>      // Handle: SHT_REL and SHT_RELA sections:
>>      // Increment over the sections, when REL/RELA section types are found
>> add
>>      // the contents to the RelocationReferences map.
>> -    llvm::object::section_iterator sit(_objFile->begin_sections());
>> -    llvm::object::section_iterator sie(_objFile->end_sections());
>> +    section_iterator sit(_objFile->begin_sections());
>> +    section_iterator sie(_objFile->end_sections());
>>      for (; sit != sie; sit.increment(EC)) {
>>        if (EC)
>>          return;
>> @@ -127,8 +123,8 @@
>>
>>      // Increment over all the symbols collecting atoms and symbol names
>> for
>>      // later use.
>> -    llvm::object::symbol_iterator it(_objFile->begin_symbols());
>> -    llvm::object::symbol_iterator ie(_objFile->end_symbols());
>> +    symbol_iterator it(_objFile->begin_symbols());
>> +    symbol_iterator ie(_objFile->end_symbols());
>>
>>      for (; it != ie; it.increment(EC)) {
>>        if (EC)
>> @@ -146,19 +142,19 @@
>>
>>        if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
>>          // Create an absolute atom.
>> -        auto *newAtom = new (_readerStorage.Allocate
>> -                       <ELFAbsoluteAtom<target_endianness, is64Bits> >
>> ())
>> -                        ELFAbsoluteAtom<target_endianness, is64Bits>
>> -                          (*this, symbolName, symbol, symbol->st_value);
>> +        auto *newAtom = new (_readerStorage.Allocate<
>> +          ELFAbsoluteAtom<target_endianness, max_align, is64Bits> > ())
>> +          ELFAbsoluteAtom<target_endianness, max_align, is64Bits>(
>> +            *this, symbolName, symbol, symbol->st_value);
>>
>>          _absoluteAtoms._atoms.push_back(newAtom);
>>          _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
>>        } else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
>>          // Create an undefined atom.
>> -        auto *newAtom = new (_readerStorage.Allocate
>> -                       <ELFUndefinedAtom<target_endianness, is64Bits> >
>> ())
>> -                        ELFUndefinedAtom<target_endianness, is64Bits>
>> -                          (*this, symbolName, symbol);
>> +        auto *newAtom = new (_readerStorage.Allocate<
>> +          ELFUndefinedAtom<target_endianness, max_align, is64Bits> > ())
>> +          ELFUndefinedAtom<target_endianness, max_align, is64Bits>(
>> +            *this, symbolName, symbol);
>>
>>          _undefinedAtoms._atoms.push_back(newAtom);
>>          _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
>> @@ -176,7 +172,7 @@
>>            sectionSymbols[section].push_back(symbol);
>>          } else {
>>            llvm::errs() << "Unable to create atom for: " << symbolName <<
>> "\n";
>> -          EC = llvm::object::object_error::parse_failed;
>> +          EC = object_error::parse_failed;
>>            return;
>>          }
>>        }
>> @@ -233,10 +229,10 @@
>>          for (auto &rai : _relocationAddendRefences[sectionName]) {
>>            if ((rai->r_offset >= (*si)->st_value) &&
>>                (rai->r_offset < (*si)->st_value+contentSize)) {
>> -            auto *ERef = new (_readerStorage.Allocate
>> -                         <ELFReference<target_endianness, is64Bits> > ())
>> -                          ELFReference<target_endianness, is64Bits> (
>> -                          rai, rai->r_offset-(*si)->st_value, nullptr);
>> +            auto *ERef = new (_readerStorage.Allocate<
>> +              ELFReference<target_endianness, max_align, is64Bits> > ())
>> +              ELFReference<target_endianness, max_align, is64Bits> (
>> +                rai, rai->r_offset-(*si)->st_value, nullptr);
>>
>>              _references.push_back(ERef);
>>            }
>> @@ -246,22 +242,21 @@
>>          for (auto &ri : _relocationReferences[sectionName]) {
>>            if (((ri)->r_offset >= (*si)->st_value) &&
>>                ((ri)->r_offset < (*si)->st_value+contentSize)) {
>> -            auto *ERef = new (_readerStorage.Allocate
>> -                         <ELFReference<target_endianness, is64Bits> > ())
>> -                          ELFReference<target_endianness, is64Bits> (
>> -                         (ri), (ri)->r_offset-(*si)->st_value, nullptr);
>> +            auto *ERef = new (_readerStorage.Allocate<
>> +              ELFReference<target_endianness, max_align, is64Bits> > ())
>> +              ELFReference<target_endianness, max_align, is64Bits> (
>> +                (ri), (ri)->r_offset-(*si)->st_value, nullptr);
>>
>>              _references.push_back(ERef);
>>            }
>>          }
>>
>>          // Create the DefinedAtom and add it to the list of DefinedAtoms.
>> -        auto *newAtom = new (_readerStorage.Allocate
>> -                       <ELFDefinedAtom<target_endianness, is64Bits> > ())
>> -                        ELFDefinedAtom<target_endianness, is64Bits>
>> -                           (*this, symbolName, sectionName,
>> -                             *si, i.first, symbolData,
>> -                             referenceStart, _references.size(),
>> _references);
>> +        auto *newAtom = new (_readerStorage.Allocate<
>> +          ELFDefinedAtom<target_endianness, max_align, is64Bits> > ())
>> +          ELFDefinedAtom<target_endianness, max_align, is64Bits>(
>> +            *this, symbolName, sectionName, *si, i.first, symbolData,
>> +            referenceStart, _references.size(), _references);
>>
>>          _definedAtoms._atoms.push_back(newAtom);
>>          _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
>> @@ -301,7 +296,7 @@
>>    }
>>
>>  private:
>> -  std::unique_ptr<llvm::object::ELFObjectFile<target_endianness,
>> is64Bits> >
>> +  std::unique_ptr<ELFObjectFile<target_endianness, max_align, is64Bits> >
>>        _objFile;
>>    atom_collection_vector<DefinedAtom>       _definedAtoms;
>>    atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
>> @@ -318,7 +313,8 @@
>>    std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
>>             _relocationReferences;
>>
>> -  std::vector<ELFReference<target_endianness, is64Bits> *> _references;
>> +  std::vector<ELFReference<target_endianness, max_align, is64Bits> *>
>> +    _references;
>>    llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
>>
>>    llvm::BumpPtrAllocator _readerStorage;
>> @@ -344,24 +340,56 @@
>>      llvm::sys::LLVMFileType fileType =
>>            llvm::sys::IdentifyFileType(mb->getBufferStart(),
>>
>> static_cast<unsigned>(mb->getBufferSize()));
>> +
>> +    std::size_t MaxAlignment =
>> +      1ULL <<
>> llvm::CountTrailingZeros_64(uintptr_t(mb->getBufferStart()));
>> +
>>      switch (fileType) {
>>      case llvm::sys::ELF_Relocatable_FileType:
>> -      Ident = llvm::object::getElfArchType(&*mb);
>> +      Ident = getElfArchType(&*mb);
>>        // Instantiate the correct FileELF template instance based on the
>> Ident
>>        // pair. Once the File is created we push the file to the vector of
>> files
>>        // already created during parser's life.
>>        if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
>>            == llvm::ELF::ELFDATA2LSB) {
>> -        f.reset(new FileELF<llvm::support::little, false>(std::move(mb),
>> ec));
>> +        if (MaxAlignment >= 4)
>> +          f.reset(
>> +            new FileELF<llvm::support::little, 4, false>(std::move(mb),
>> ec));
>> +        else if (MaxAlignment >= 2)
>> +          f.reset(
>> +            new FileELF<llvm::support::little, 2, false>(std::move(mb),
>> ec));
>> +        else
>> +          llvm_unreachable("Invalid alignment for ELF file!");
>>        } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
>>            == llvm::ELF::ELFDATA2MSB) {
>> -        f.reset(new FileELF<llvm::support::big, false> (std::move(mb),
>> ec));
>> +        if (MaxAlignment >= 4)
>> +          f.reset(
>> +            new FileELF<llvm::support::big, 4, false>(std::move(mb),
>> ec));
>> +        else if (MaxAlignment >= 2)
>> +          f.reset(
>> +            new FileELF<llvm::support::big, 2, false>(std::move(mb),
>> ec));
>> +        else
>> +          llvm_unreachable("Invalid alignment for ELF file!");
>>        } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
>>            == llvm::ELF::ELFDATA2MSB) {
>> -        f.reset(new FileELF<llvm::support::big, true> (std::move(mb),
>> ec));
>> +        if (MaxAlignment >= 8)
>> +          f.reset(
>> +            new FileELF<llvm::support::big, 8, true>(std::move(mb), ec));
>> +        else if (MaxAlignment >= 2)
>> +          f.reset(
>> +            new FileELF<llvm::support::big, 2, true>(std::move(mb), ec));
>> +        else
>> +          llvm_unreachable("Invalid alignment for ELF file!");
>>        } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
>>            == llvm::ELF::ELFDATA2LSB) {
>> -        f.reset(new FileELF<llvm::support::little, true> (std::move(mb),
>> ec));
>> +        if (MaxAlignment >= 8)
>> +          f.reset(
>> +            new FileELF<llvm::support::little, 8, true>(std::move(mb),
>> ec));
>> +        else if (MaxAlignment >= 2)
>> +          f.reset(
>> +            new FileELF<llvm::support::little, 2, true>(std::move(mb),
>> ec));
>> +        else
>> +          llvm_unreachable("Invalid alignment for ELF file!");
>>        }
>>        if (!ec)
>>          result.push_back(std::move(f));
>>
>> Modified: lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp?rev=171526&r1=171525&r2=171526&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp (original)
>> +++ lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp Fri Jan  4 15:09:21 2013
>> @@ -45,33 +45,36 @@
>>  using namespace llvm::object;
>>  namespace lld {
>>  namespace elf {
>> -
>> -template<support::endianness target_endianness, bool is64Bits>
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class ELFExecutableWriter;
>>
>>  /// \brief The ELFWriter class is a base class for the linker to write
>>  ///        various kinds of ELF files.
>>  class ELFWriter : public Writer {
>> -  public:
>> -    ELFWriter() { }
>> +public:
>> +  ELFWriter() { }
>>
>> -  public:
>> -    /// \brief builds the chunks that needs to be written to the output
>> -    ///        ELF file
>> -    virtual void buildChunks(const lld::File &file) = 0;
>> +public:
>> +  /// \brief builds the chunks that needs to be written to the output
>> +  ///        ELF file
>> +  virtual void buildChunks(const lld::File &file) = 0;
>>
>> -    /// \brief Writes the chunks into the output file specified by path
>> -    virtual error_code writeFile(const lld::File &File, StringRef path) =
>> 0;
>> +  /// \brief Writes the chunks into the output file specified by path
>> +  virtual error_code writeFile(const lld::File &File, StringRef path) =
>> 0;
>>
>> -    /// \brief Writes the chunks into the output file specified by path
>> -    virtual uint64_t addressOfAtom(const Atom *atom) = 0;
>> +  /// \brief Writes the chunks into the output file specified by path
>> +  virtual uint64_t addressOfAtom(const Atom *atom) = 0;
>>
>> -    /// \brief Return the processing function to apply Relocations
>> -    virtual KindHandler *kindHandler()  = 0;
>> +  /// \brief Return the processing function to apply Relocations
>> +  virtual KindHandler *kindHandler()  = 0;
>>  };
>>
>>  /// \brief A chunk is a contiguous region of space
>> -template<support::endianness target_endianness, bool is64Bits>
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class Chunk {
>>  public:
>>
>> @@ -83,7 +86,7 @@
>>      K_ELFSection, // Section
>>      K_ELFSectionHeader // Section header
>>    };
>> -  Chunk(StringRef name, Kind kind)
>> +  Chunk(StringRef name, Kind kind)
>>      : _name(name)
>>      , _kind(kind)
>>      , _fsize(0)
>> @@ -94,9 +97,9 @@
>>      , _start(0)
>>      , _fileoffset(0) {}
>>    virtual             ~Chunk() {}
>> -  // Does the chunk occupy disk space
>> +  // Does the chunk occupy disk space
>>    virtual bool        occupiesNoDiskSpace() const {
>> -    return false;
>> +    return false;
>>    }
>>    // The name of the chunk
>>    StringRef name() const { return _name; }
>> @@ -121,8 +124,8 @@
>>    // Does the chunk occupy memory during execution ?
>>    uint64_t            memSize() const { return _msize; }
>>    void               setMemSize(uint64_t msize) { _msize = msize; }
>> -  // Writer the chunk
>> -  virtual void       write(ELFWriter *writer,
>> +  // Writer the chunk
>> +  virtual void       write(ELFWriter *writer,
>>                             OwningPtr<FileOutputBuffer> &buffer) = 0;
>>    // Finalize the chunk before writing
>>    virtual void       finalize() = 0;
>> @@ -141,7 +144,7 @@
>>
>>  /// \brief The ELFLayoutOptions encapsulates the options used by all
>> Layouts
>>  ///        Examples of the ELFLayoutOptions would be a script that would
>> be used
>> -///        to drive the layout
>> +///        to drive the layout
>>  class ELFLayoutOptions {
>>  public:
>>    ELFLayoutOptions() { }
>> @@ -159,10 +162,10 @@
>>    StringRef _script;
>>  };
>>
>> -/// \brief The ELFLayout is an abstract class for managing the final
>> layout for
>> +/// \brief The ELFLayout is an abstract class for managing the final
>> layout for
>>  ///        the kind of binaries(Shared Libraries / Relocatables /
>> Executables 0
>> -///        Each architecture (Hexagon, PowerPC, MIPS) would have a
>> concrete
>> -///        subclass derived from ELFLayout for generating each binary
>> thats
>> +///        Each architecture (Hexagon, PowerPC, MIPS) would have a
>> concrete
>> +///        subclass derived from ELFLayout for generating each binary
>> thats
>>  //         needed by the lld linker
>>  class ELFLayout {
>>  public:
>> @@ -176,7 +179,7 @@
>>                          (const StringRef name,
>>                           int32_t contentType,
>>                           int32_t contentPerm) = 0;
>> -  /// append the Atom to the layout and create appropriate sections
>> +  /// append the Atom to the layout and create appropriate sections
>>    virtual error_code addAtom(const Atom *atom) = 0;
>>    /// find the Atom Address in the current layout
>>    virtual bool findAtomAddrByName(const StringRef name, uint64_t &addr) =
>> 0;
>> @@ -189,8 +192,8 @@
>>
>>  public:
>>    ELFLayout() {}
>> -  ELFLayout(WriterOptionsELF &writerOptions,
>> -            ELFLayoutOptions &layoutOptions)
>> +  ELFLayout(WriterOptionsELF &writerOptions,
>> +            ELFLayoutOptions &layoutOptions)
>>      : _writerOptions(writerOptions)
>>      , _layoutOptions(layoutOptions) {}
>>    virtual ~ELFLayout() { }
>> @@ -200,13 +203,14 @@
>>    ELFLayoutOptions _layoutOptions;
>>  };
>>
>> -
>>  /// \brief A section contains a set of atoms that have similiar
>> properties
>>  ///        The atoms that have similiar properties are merged to form a
>> section
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class Section : public Chunk<target_endianness, is64Bits> {
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class Section : public Chunk<target_endianness, max_align, is64Bits> {
>>  public:
>> -  // The Kind of section that the object represents
>> +  // The Kind of section that the object represents
>>    enum SectionKind {
>>      K_Default,
>>      K_SymbolTable,
>> @@ -214,13 +218,13 @@
>>    };
>>    // Create a section object, the section is set to the default type if
>> the
>>    // caller doesnot set it
>> -  Section(const StringRef sectionName,
>> +  Section(const StringRef sectionName,
>>            const int32_t contentType,
>>            const int32_t contentPermissions,
>>            const int32_t order,
>> -          const SectionKind kind = K_Default)
>> -    : Chunk<target_endianness, is64Bits>
>> -      (sectionName, Chunk<target_endianness, is64Bits>::K_ELFSection)
>> +          const SectionKind kind = K_Default)
>> +    : Chunk<target_endianness,  max_align, is64Bits>(
>> +       sectionName, Chunk<target_endianness, max_align,
>> is64Bits>::K_ELFSection)
>>      , _contentType(contentType)
>>      , _contentPermissions(contentPermissions)
>>      , _sectionKind(kind)
>> @@ -250,7 +254,7 @@
>>      return retOffset;
>>    }
>>
>> -  // \brief Append an atom to a Section. The atom gets pushed into a
>> vector
>> +  // \brief Append an atom to a Section. The atom gets pushed into a
>> vector
>>    // contains the atom, the atom file offset, the atom virtual address
>>    // the atom file offset is aligned appropriately as set by the Reader
>>    void appendAtom(const Atom *atom) {
>> @@ -259,7 +263,7 @@
>>      assert(atom != nullptr && "Expecting the atom to be a DefinedAtom");
>>      DefinedAtom::Alignment atomAlign = definedAtom->alignment();
>>      uint64_t align2 = 1u << atomAlign.powerOf2;
>> -    // Align the atom to the required modulus/ align the file offset and
>> the
>> +    // Align the atom to the required modulus/ align the file offset and
>> the
>>      // memory offset seperately this is required so that BSS symbols are
>> handled
>>      // properly as the BSS symbols only occupy memory size and not file
>> size
>>      uint64_t fOffset = alignOffset(this->fileSize(), atomAlign);
>> @@ -286,15 +290,15 @@
>>      default:
>>        llvm_unreachable("Expecting only definedAtoms being passed here");
>>        break;
>> -    }
>> -    // Set the section alignment to the largest alignment
>> +    }
>> +    // Set the section alignment to the largest alignment
>>      // std::max doesnot support uint64_t
>> -    if (this->_align2 < align2)
>> +    if (this->_align2 < align2)
>>        this->_align2 = align2;
>>    }
>>
>> -  /// \brief Set the virtual address of each Atom in the Section. This
>> -  /// routine gets called after the linker fixes up the virtual address
>> +  /// \brief Set the virtual address of each Atom in the Section. This
>> +  /// routine gets called after the linker fixes up the virtual address
>>    /// of the section
>>    void assignVirtualAddress(uint64_t &addr) {
>>      for (auto &ai : _atoms) {
>> @@ -303,15 +307,15 @@
>>      addr += this->memSize();
>>    }
>>
>> -  /// \brief Set the file offset of each Atom in the section. This
>> routine
>> -  /// gets called after the linker fixes up the section offset
>> +  /// \brief Set the file offset of each Atom in the section. This
>> routine
>> +  /// gets called after the linker fixes up the section offset
>>    void assignOffsets(uint64_t offset) {
>>      for (auto &ai : _atoms) {
>>        ai.second.first = offset + ai.second.first;
>>      }
>>    }
>>
>> -  /// \brief Find the Atom address given a name, this is needed to to
>> properly
>> +  /// \brief Find the Atom address given a name, this is needed to to
>> properly
>>    ///  apply relocation. The section class calls this to find the atom
>> address
>>    ///  to fix the relocation
>>    bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
>> @@ -329,7 +333,7 @@
>>      return _contentType == DefinedAtom::typeZeroFill;
>>    }
>>
>> -  /// \brief The permission of the section is the most permissive
>> permission
>> +  /// \brief The permission of the section is the most permissive
>> permission
>>    /// of all atoms that the section contains
>>    void setContentPermissions(int32_t perm) {
>>      _contentPermissions = std::max(perm, _contentPermissions);
>> @@ -343,17 +347,17 @@
>>
>>      case DefinedAtom::permR__:
>>          return llvm::ELF::SHF_ALLOC;
>> -
>> +
>>      case DefinedAtom::permR_X:
>>          return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR;
>> -
>> +
>>      case DefinedAtom::permRW_:
>>      case DefinedAtom::permRW_L:
>>          return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE;
>> -
>> +
>>      case DefinedAtom::permRWX:
>> -        return llvm::ELF::SHF_ALLOC |
>> -                llvm::ELF::SHF_WRITE |
>> +        return llvm::ELF::SHF_ALLOC |
>> +                llvm::ELF::SHF_WRITE |
>>                  llvm::ELF::SHF_EXECINSTR;
>>
>>      default:
>> @@ -367,7 +371,7 @@
>>      return _contentPermissions;
>>    }
>>
>> -  /// \brief Return the section type, the returned value is recorded in
>> the
>> +  /// \brief Return the section type, the returned value is recorded in
>> the
>>    /// sh_type field of the Section Header
>>    int type() {
>>      switch (_contentType) {
>> @@ -386,7 +390,7 @@
>>      }
>>    }
>>
>> -  /// \brief Returns the section link field, the returned value is
>> +  /// \brief Returns the section link field, the returned value is
>>    ///        recorded in the sh_link field of the Section Header
>>    int link() const {
>>      return _link;
>> @@ -396,15 +400,15 @@
>>      _link = link;
>>    }
>>
>> -  /// \brief Returns the section entsize field, the returned value is
>> +  /// \brief Returns the section entsize field, the returned value is
>>    ///        recorded in the sh_entsize field of the Section Header
>>    int entsize() const {
>>      return _entSize;
>>    }
>>
>> -  /// \brief Returns the shinfo field, the returned value is
>> +  /// \brief Returns the shinfo field, the returned value is
>>    ///        recorded in the sh_info field of the Section Header
>> -  int shinfo() const {
>> +  int shinfo() const {
>>      return _shInfo;
>>    }
>>
>> @@ -437,15 +441,17 @@
>>    }
>>
>>    /// \brief for LLVM style RTTI information
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->kind() == Chunk<target_endianness, is64Bits>::K_ELFSection;
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->kind() ==
>> +      Chunk<target_endianness, max_align, is64Bits>::K_ELFSection;
>>    }
>>
>>    /// \brief Finalize the section contents before writing
>>    void finalize() { }
>>
>> -  /// \brief Write the section and the atom contents to the buffer
>> -  void write(ELFWriter *writer,
>> +  /// \brief Write the section and the atom contents to the buffer
>> +  void write(ELFWriter *writer,
>>               OwningPtr<FileOutputBuffer> &buffer) {
>>      uint8_t *chunkBuffer = buffer->getBufferStart();
>>      for (auto &ai : _atoms) {
>> @@ -466,7 +472,7 @@
>>            assert(0 && "Found the target to be NULL");
>>          uint64_t fixupAddress = writer->addressOfAtom(ai.first) + offset;
>>          // apply the relocation
>> -        writer->kindHandler()->applyFixup(ref->kind(),
>> +        writer->kindHandler()->applyFixup(ref->kind(),
>>                                            ref->addend(),
>>                                            &atomContent[offset],
>>                                            fixupAddress,
>> @@ -476,7 +482,7 @@
>>    }
>>
>>    /// Atom Iterators
>> -  typedef typename std::vector<std::pair<const Atom *,
>> +  typedef typename std::vector<std::pair<const Atom *,
>>            std::pair<uint64_t, uint64_t>>>::iterator atom_iter;
>>
>>    atom_iter atoms_begin() { return _atoms.begin(); }
>> @@ -496,15 +502,17 @@
>>    int64_t _entSize;
>>    int64_t _shInfo;
>>    int64_t _link;
>> -};
>> +};
>>
>> -/// \brief A MergedSections represents a set of sections grouped by the
>> same name
>> -///        The output file that gets written by the linker has sections
>> grouped
>> -///        by similiar names
>> -template<support::endianness target_endianness, bool is64Bits>
>> +/// \brief A MergedSections represents a set of sections grouped by the
>> same
>> +/// name. The output file that gets written by the linker has sections
>> grouped
>> +/// by similiar names
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class MergedSections {
>>  public:
>> -  MergedSections(StringRef name)
>> +  MergedSections(StringRef name)
>>      : _name(name)
>>      ,_hasSegment(false)
>>      ,_ordinal(0)
>> @@ -519,17 +527,17 @@
>>      ,_align2(0)
>>      ,_kind(0)
>>      ,_type(0) { }
>> -
>> +
>>    // Set the MergedSections is associated with a segment
>>    void setHasSegment() { _hasSegment = true; }
>>
>> -  /// Sets the ordinal
>> +  /// Sets the ordinal
>>    void setOrdinal(uint64_t ordinal) {
>>      _ordinal = ordinal;
>>    }
>>
>> -  /// Sets the Memory size
>> -  void setMemSize(uint64_t memsz) {
>> +  /// Sets the Memory size
>> +  void setMemSize(uint64_t memsz) {
>>      _memSize = memsz;
>>    }
>>
>> @@ -538,7 +546,8 @@
>>      _size = fsiz;
>>    }
>>
>> -  // The offset of the first section contained in the merged section is
>> contained here
>> +  // The offset of the first section contained in the merged section is
>> +  // contained here
>>    void setFileOffset(uint64_t foffset) {
>>      _fileOffset = foffset;
>>    }
>> @@ -550,12 +559,14 @@
>>
>>    // Appends a section into the list of sections that are part of this
>> Merged
>>    // Section
>> -  void appendSection(Chunk<target_endianness, is64Bits> *c) {
>> -    if (c->align2() > _align2)
>> +  void appendSection(Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    if (c->align2() > _align2)
>>        _align2 = c->align2();
>> -    if (c->kind() == Chunk<target_endianness, is64Bits>::K_ELFSection) {
>> -      Section<target_endianness, is64Bits> *section;
>> -      section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(c);
>> +    if (c->kind() ==
>> +          Chunk<target_endianness, max_align, is64Bits>::K_ELFSection) {
>> +      Section<target_endianness, max_align, is64Bits> *section;
>> +      section =
>> +        llvm::dyn_cast<Section<target_endianness, max_align,
>> is64Bits>>(c);
>>        _link = section->link();
>>        _shInfo = section->shinfo();
>>        _entSize = section->entsize();
>> @@ -568,8 +579,8 @@
>>    }
>>
>>    // Iterators
>> -  typedef typename std::vector<Chunk<target_endianness, is64Bits>
>> *>::iterator
>> -
>> ChunkIter;
>> +  typedef typename std::vector<
>> +    Chunk<target_endianness, max_align, is64Bits> *>::iterator ChunkIter;
>>
>>    ChunkIter begin_sections() { return _sections.begin(); }
>>
>> @@ -619,21 +630,23 @@
>>    uint64_t _align2;
>>    int64_t _kind;
>>    int64_t _type;
>> -  std::vector<Chunk<target_endianness, is64Bits> *> _sections;
>> +  std::vector<Chunk<target_endianness, max_align, is64Bits> *> _sections;
>>  };
>>
>> -/// \brief A segment can be divided into segment slices
>> -///        depending on how the segments can be split
>> -template<support::endianness target_endianness, bool is64Bits>
>> +/// \brief A segment can be divided into segment slices
>> +///        depending on how the segments can be split
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class SegmentSlice {
>>  public:
>> -  typedef typename std::vector<Section<target_endianness, is64Bits>
>> *>::iterator
>> -
>> sectionIter;
>> +  typedef typename std::vector<
>> +    Section<target_endianness, max_align, is64Bits> *>::iterator
>> sectionIter;
>>
>>    SegmentSlice() { }
>>
>>    /// Set the segment slice so that it begins at the offset specified
>> -  /// by fileoffset and set the start of the slice to be s and the end
>> +  /// by fileoffset and set the start of the slice to be s and the end
>>    /// of the slice to be e
>>    void set(uint64_t fileoffset, int32_t s, int e) {
>>      _startSection = s;
>> @@ -674,8 +687,9 @@
>>
>>    void setAlign(uint64_t align) { _align2 = align; }
>>
>> -  static bool compare_slices(SegmentSlice<target_endianness, is64Bits>
>> *a,
>> -                             SegmentSlice<target_endianness, is64Bits>
>> *b) {
>> +  static bool compare_slices(
>> +      SegmentSlice<target_endianness, max_align, is64Bits> *a,
>> +      SegmentSlice<target_endianness, max_align, is64Bits> *b) {
>>      return (a->startSection() < b->startSection());
>>    }
>>
>> @@ -699,19 +713,21 @@
>>  /// \brief A segment contains a set of sections, that have similiar
>> properties
>>  //  the sections are already seperated based on different flags and
>> properties
>>  //  the segment is just a way to concatenate sections to segments
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class Segment : public Chunk<target_endianness, is64Bits> {
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class Segment : public Chunk<target_endianness, max_align, is64Bits> {
>>  public:
>> -  typedef typename std::vector
>> -       <SegmentSlice<target_endianness, is64Bits> *>::iterator
>> slice_iter;
>> -  typedef typename
>> -        std::vector<Section<target_endianness, is64Bits> *>::iterator
>> SectionIter;
>> +  typedef typename std::vector<SegmentSlice<
>> +    target_endianness, max_align, is64Bits> *>::iterator slice_iter;
>> +  typedef typename std::vector<
>> +    Section<target_endianness, max_align, is64Bits> *>::iterator
>> SectionIter;
>>
>>    Segment(const StringRef name,
>>            const ELFLayout::SegmentType type,
>>            const WriterOptionsELF &options)
>> -    : Chunk<target_endianness, is64Bits>(name
>> -    , Chunk<target_endianness, is64Bits>::K_ELFSegment)
>> +    : Chunk<target_endianness, max_align, is64Bits>(name,
>> +                    Chunk<target_endianness, max_align,
>> is64Bits>::K_ELFSegment)
>>      , _segmentType(type)
>>      , _flags(0)
>>      , _atomflags(0)
>> @@ -721,7 +737,7 @@
>>    }
>>
>>    /// append a section to a segment
>> -  void append(Section<target_endianness, is64Bits> *section) {
>> +  void append(Section<target_endianness, max_align, is64Bits> *section) {
>>      _sections.push_back(section);
>>      if (_flags < section->flags())
>>        _flags = section->flags();
>> @@ -738,12 +754,11 @@
>>    /// All Read Write Execute segments follow
>>    /// All Read Execute segments appear next
>>    /// All Read only segments appear first
>> -  /// All Write execute segments follow
>> -  static bool compareSegments(Segment<target_endianness, is64Bits> *sega,
>> -                              Segment<target_endianness, is64Bits> *segb)
>> -  {
>> -
>> -    if (sega->atomflags() < segb->atomflags())
>> +  /// All Write execute segments follow
>> +  static bool compareSegments(
>> +      Segment<target_endianness, max_align, is64Bits> *sega,
>> +      Segment<target_endianness, max_align, is64Bits> *segb) {
>> +    if (sega->atomflags() < segb->atomflags())
>>        return false;
>>      return true;
>>    }
>> @@ -756,13 +771,13 @@
>>    /// The algorithm starts off by assigning the startOffset thats passed
>> in as
>>    /// parameter to the first section in the segment, if the difference
>> between
>>    /// the newly computed offset is greater than a page, then we create a
>> segment
>> -  /// slice, as it would be a waste of virtual memory just to be filled
>> with
>> +  /// slice, as it would be a waste of virtual memory just to be filled
>> with
>>    /// zeroes
>>    void assignOffsets(uint64_t startOffset) {
>>      int startSection = 0;
>>      int currSection = 0;
>>      SectionIter startSectionIter, endSectionIter;
>> -    // slice align is set to the max alignment of the chunks that are
>> +    // slice align is set to the max alignment of the chunks that are
>>      // contained in the slice
>>      uint64_t sliceAlign = 0;
>>      // Current slice size
>> @@ -777,7 +792,8 @@
>>      for (auto si = _sections.begin(); si != _sections.end(); ++si) {
>>        if (isFirstSection) {
>>          // align the startOffset to the section alignment
>> -        uint64_t newOffset = llvm::RoundUpToAlignment(startOffset,
>> (*si)->align2());
>> +        uint64_t newOffset =
>> +          llvm::RoundUpToAlignment(startOffset, (*si)->align2());
>>          curSliceFileOffset = newOffset;
>>          sliceAlign = (*si)->align2();
>>          this->setFileOffset(startOffset);
>> @@ -786,8 +802,9 @@
>>          isFirstSection = false;
>>        } else {
>>          uint64_t curOffset = curSliceFileOffset + curSliceSize;
>> -        uint64_t newOffset = llvm::RoundUpToAlignment(curOffset,
>> (*si)->align2());
>> -        SegmentSlice<target_endianness, is64Bits> *slice = nullptr;
>> +        uint64_t newOffset =
>> +          llvm::RoundUpToAlignment(curOffset, (*si)->align2());
>> +        SegmentSlice<target_endianness, max_align, is64Bits> *slice =
>> nullptr;
>>          // If the newOffset computed is more than a page away, lets
>> create
>>          // a seperate segment, so that memory is not used up while
>> running
>>          if ((newOffset - curOffset) > _options.pageSize()) {
>> @@ -799,16 +816,17 @@
>>              }
>>            }
>>            if (!slice) {
>> -            slice = new (_segmentAllocate.Allocate
>> -                         <SegmentSlice<target_endianness, is64Bits>>())
>> -                         SegmentSlice<target_endianness, is64Bits>();
>> +            slice = new (_segmentAllocate.Allocate<
>> +              SegmentSlice<target_endianness, max_align, is64Bits>>())
>> +              SegmentSlice<target_endianness, max_align, is64Bits>();
>>              _segmentSlices.push_back(slice);
>>            }
>>            slice->set(curSliceFileOffset, startSection, currSection);
>>            slice->setSections(startSectionIter, endSectionIter);
>>            slice->setSize(curSliceSize);
>>            slice->setAlign(sliceAlign);
>> -          uint64_t newPageOffset = llvm::RoundUpToAlignment(curOffset,
>> _options.pageSize());
>> +          uint64_t newPageOffset =
>> +            llvm::RoundUpToAlignment(curOffset, _options.pageSize());
>>            newOffset = llvm::RoundUpToAlignment(newPageOffset,
>> (*si)->align2());
>>            curSliceFileOffset = newOffset;
>>            startSectionIter = endSectionIter;
>> @@ -827,7 +845,7 @@
>>        currSection++;
>>        endSectionIter = si;
>>      }
>> -    SegmentSlice<target_endianness, is64Bits> *slice = nullptr;
>> +    SegmentSlice<target_endianness, max_align, is64Bits> *slice =
>> nullptr;
>>      for (auto sei = slices_begin(); sei != slices_end(); ++sei) {
>>        // TODO: add std::find
>>        if ((*sei)->startSection() == startSection) {
>> @@ -837,8 +855,8 @@
>>      }
>>      if (!slice) {
>>        slice = new (_segmentAllocate.Allocate
>> -                   <SegmentSlice<target_endianness, is64Bits>>())
>> -                   SegmentSlice<target_endianness, is64Bits>();
>> +                   <SegmentSlice<target_endianness, max_align,
>> is64Bits>>())
>> +                   SegmentSlice<target_endianness, max_align,
>> is64Bits>();
>>        _segmentSlices.push_back(slice);
>>      }
>>      slice->set(curSliceFileOffset, startSection, currSection);
>> @@ -846,15 +864,15 @@
>>      slice->setSize(curSliceSize);
>>      slice->setAlign(sliceAlign);
>>      this->_fsize = curSliceFileOffset - startOffset + curSliceSize;
>> -    std::stable_sort(slices_begin(), slices_end(),
>> -                     SegmentSlice<target_endianness,
>> is64Bits>::compare_slices);
>> +    std::stable_sort(slices_begin(), slices_end(),
>> +      SegmentSlice<target_endianness, max_align,
>> is64Bits>::compare_slices);
>>    }
>>
>>    /// \brief Assign virtual addresses to the slices
>>    void assignVirtualAddress(uint64_t &addr, bool isFirstSegment) {
>>      for (auto sei = slices_begin(), see = slices_end(); sei != see;
>> ++sei) {
>>        bool firstSlice = (sei == slices_begin());
>> -      // The first segment has distinct since it contains the
>> +      // The first segment has distinct since it contains the
>>        // ELF header and the Program Header, if we get to the first
>> segment
>>        // and the first slice, set it to the baseaddress
>>        // which is the segment address
>> @@ -867,7 +885,7 @@
>>          addr = llvm::RoundUpToAlignment(addr, (*sei)->align2());
>>        }
>>        bool virtualAddressSet = false;
>> -      for (auto si = (*sei)->sections_begin(), se =
>> (*sei)->sections_end();
>> +      for (auto si = (*sei)->sections_begin(), se =
>> (*sei)->sections_end();
>>                                                 si != se; ++si) {
>>          // Align the section address
>>          addr = llvm::RoundUpToAlignment(addr, (*si)->align2());
>> @@ -891,10 +909,10 @@
>>      return _segmentSlices.end();
>>    }
>>
>> -  // Write the Segment
>> +  // Write the Segment
>>    void write(ELFWriter *writer, OwningPtr<FileOutputBuffer> &buffer) {
>>      for (auto sei = slices_begin(), see = slices_end(); sei != see;
>> ++sei) {
>> -      for (auto si = (*sei)->sections_begin(), se =
>> (*sei)->sections_end();
>> +      for (auto si = (*sei)->sections_begin(), se =
>> (*sei)->sections_end();
>>                                                 si != se; ++si) {
>>          (*si)->write(writer, buffer);
>>        }
>> @@ -904,9 +922,11 @@
>>    // Finalize the segment, before we want to write to the output file
>>    void finalize() { }
>>
>> -  // For LLVM RTTI
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->kind() == Chunk<target_endianness, is64Bits>::K_ELFSegment;
>> +  // For LLVM RTTI
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->kind() ==
>> +      Chunk<target_endianness, max_align, is64Bits>::K_ELFSegment;
>>    }
>>
>>    // Getters
>> @@ -936,8 +956,9 @@
>>    }
>>
>>  private:
>> -  std::vector<Section<target_endianness, is64Bits> *> _sections;
>> -  std::vector<SegmentSlice<target_endianness, is64Bits> *>
>> _segmentSlices;
>> +  std::vector<Section<target_endianness, max_align, is64Bits> *>
>> _sections;
>> +  std::vector<SegmentSlice<target_endianness, max_align, is64Bits> *>
>> +    _segmentSlices;
>>    ELFLayout::SegmentType _segmentType;
>>    int64_t _flags;
>>    int64_t _atomflags;
>> @@ -946,17 +967,18 @@
>>  };
>>
>>  /// \brief The class represents the ELF String Table
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class ELFStringTable : public Section<target_endianness, is64Bits> {
>> -
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class ELFStringTable : public Section<target_endianness, max_align,
>> is64Bits> {
>>  public:
>> -  ELFStringTable(const char *str,
>> -                 int32_t order):
>> -                            Section<target_endianness, is64Bits>(str,
>> -
>> llvm::ELF::SHT_STRTAB,
>> -
>> DefinedAtom::perm___,
>> -                                                         order,
>> -                            Section<target_endianness,
>> is64Bits>::K_StringTable) {
>> +  ELFStringTable(const char *str, int32_t order)
>> +    : Section<target_endianness, max_align, is64Bits>(
>> +        str,
>> +        llvm::ELF::SHT_STRTAB,
>> +        DefinedAtom::perm___,
>> +        order,
>> +        Section<target_endianness, max_align, is64Bits>::K_StringTable) {
>>      // the string table has a NULL entry for which
>>      // add an empty string
>>      _strings.push_back("");
>> @@ -965,12 +987,10 @@
>>      this->setOrder(order);
>>    }
>>
>> -  static inline bool classof(ELFStringTable<target_endianness, is64Bits>
>> *s) {
>> -    return true;
>> -  }
>> -
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->kind() == Section<target_endianness,
>> is64Bits>::K_StringTable;
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->kind() ==
>> +      Section<target_endianness, max_align, is64Bits>::K_StringTable;
>>    }
>>
>>    uint64_t addString(const StringRef symname) {
>> @@ -980,7 +1000,7 @@
>>      return offset;
>>    }
>>
>> -  void write(ELFWriter *writer,
>> +  void write(ELFWriter *writer,
>>               OwningPtr<FileOutputBuffer> &buffer) {
>>      uint8_t *chunkBuffer = buffer->getBufferStart();
>>      uint8_t *dest = chunkBuffer + this->fileOffset();
>> @@ -998,35 +1018,34 @@
>>    std::vector<StringRef> _strings;
>>  };
>>
>> -/// \brief The ELFSymbolTable class represents the symbol table in a ELF
>> file
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class ELFSymbolTable : public Section<target_endianness, is64Bits> {
>> -
>> +/// \brief The ELFSymbolTable class represents the symbol table in a ELF
>> file
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class ELFSymbolTable : public Section<target_endianness, max_align,
>> is64Bits> {
>>  public:
>> -  typedef object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
>> +  typedef object::Elf_Sym_Impl<target_endianness, max_align, is64Bits>
>> Elf_Sym;
>>
>> -  ELFSymbolTable(const char *str,
>> -                 int32_t order)
>> -    : Section<target_endianness, is64Bits>(str
>> -    , llvm::ELF::SHT_SYMTAB
>> -    , 0
>> -    , order
>> -    , Section<target_endianness, is64Bits>::K_SymbolTable) {
>> +  ELFSymbolTable(const char *str, int32_t order)
>> +    : Section<target_endianness, max_align, is64Bits>(
>> +        str,
>> +        llvm::ELF::SHT_SYMTAB,
>> +        0,
>> +        order,
>> +        Section<target_endianness, max_align, is64Bits>::K_SymbolTable) {
>>      this->setOrder(order);
>>      Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
>> -    memset ((void *)symbol,0, sizeof(Elf_Sym));
>> +    memset((void *)symbol, 0, sizeof(Elf_Sym));
>>      _symbolTable.push_back(symbol);
>>      this->_entSize = sizeof(Elf_Sym);
>>      this->_fsize = sizeof(Elf_Sym);
>>      this->_align2 = sizeof(void *);
>>    }
>>
>> -  static inline bool classof(ELFSymbolTable<target_endianness, is64Bits>
>> *s) {
>> -    return true;
>> -  }
>> -
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->kind() == Section<target_endianness,
>> is64Bits>::K_SymbolTable;
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->kind() ==
>> +      Section<target_endianness, max_align, is64Bits>::K_SymbolTable;
>>    }
>>
>>    void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr =
>> 0) {
>> @@ -1056,11 +1075,12 @@
>>        default:
>>          type = ELF::STT_NOTYPE;
>>        }
>> -      if (da->scope() == DefinedAtom::scopeTranslationUnit)
>> +      if (da->scope() == DefinedAtom::scopeTranslationUnit)
>>          binding = ELF::STB_LOCAL;
>>        else
>>          binding = ELF::STB_GLOBAL;
>> -    } else if (const AbsoluteAtom *aa = llvm::dyn_cast<const
>> AbsoluteAtom>(atom)){
>> +    } else if (const AbsoluteAtom *aa =
>> +                 llvm::dyn_cast<const AbsoluteAtom>(atom)){
>>        type = ELF::STT_OBJECT;
>>        symbol->st_shndx = ELF::SHN_ABS;
>>        switch (aa->scope()) {
>> @@ -1076,7 +1096,7 @@
>>          break;
>>        }
>>        symbol->st_value = aa->value();
>> -    }
>> +    }
>>      else {
>>       symbol->st_value = 0;
>>       type = ELF::STT_NOTYPE;
>> @@ -1087,7 +1107,8 @@
>>      this->_fsize += sizeof(Elf_Sym);
>>    }
>>
>> -  void setStringSection(ELFStringTable<target_endianness, is64Bits> *s) {
>> +  void setStringSection(
>> +      ELFStringTable<target_endianness, max_align, is64Bits> *s) {
>>      _stringSection = s;
>>    }
>>
>> @@ -1097,7 +1118,7 @@
>>      std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
>>      [](const Elf_Sym *A, const Elf_Sym *B) {
>>         return A->getBinding() < B->getBinding();
>> -    });
>> +    });
>>      uint16_t shInfo = 0;
>>      for (auto i : _symbolTable) {
>>        if (i->getBinding() != ELF::STB_LOCAL)
>> @@ -1108,9 +1129,8 @@
>>      this->setLink(_stringSection->ordinal());
>>    }
>>
>> -  void write(ELFWriter *writer,
>> +  void write(ELFWriter *writer,
>>               OwningPtr<FileOutputBuffer> &buffer) {
>> -
>>      uint8_t *chunkBuffer = buffer->getBufferStart();
>>      uint8_t *dest = chunkBuffer + this->fileOffset();
>>      for (auto sti : _symbolTable) {
>> @@ -1120,7 +1140,7 @@
>>    }
>>
>>  private:
>> -  ELFStringTable<target_endianness, is64Bits> *_stringSection;
>> +  ELFStringTable<target_endianness, max_align, is64Bits> *_stringSection;
>>    std::vector<Elf_Sym*> _symbolTable;
>>    llvm::BumpPtrAllocator _symbolAllocate;
>>    int64_t _link;
>> @@ -1128,14 +1148,16 @@
>>
>>  /// \brief An ELFHeader represents the Elf[32/64]_Ehdr structure at the
>>  ///        start of an ELF executable file.
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class ELFHeader : public Chunk<target_endianness, is64Bits> {
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class ELFHeader : public Chunk<target_endianness, max_align, is64Bits> {
>>  public:
>> -  typedef object::Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr;
>> +  typedef Elf_Ehdr_Impl<target_endianness, max_align, is64Bits> Elf_Ehdr;
>>
>>    ELFHeader()
>> -  : Chunk<target_endianness, is64Bits>("elfhdr"
>> -  , Chunk<target_endianness, is64Bits>::K_ELFHeader) {
>> +  : Chunk<target_endianness, max_align, is64Bits>(
>> +      "elfhdr", Chunk<target_endianness, max_align,
>> is64Bits>::K_ELFHeader) {
>>      memset(_eh.e_ident, 0, llvm::ELF::EI_NIDENT);
>>      e_ident(ELF::EI_MAG0, 0x7f);
>>      e_ident(ELF::EI_MAG1, 'E');
>> @@ -1160,13 +1182,14 @@
>>    void e_shstrndx(uint16_t shstrndx)   { _eh.e_shstrndx = shstrndx; }
>>    uint64_t  fileSize()                 { return sizeof (Elf_Ehdr); }
>>
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->Kind() ==  Chunk<target_endianness, is64Bits>::K_ELFHeader;
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->Kind() ==
>> +      Chunk<target_endianness, max_align, is64Bits>::K_ELFHeader;
>>    }
>>
>> -  void write(ELFWriter *writer,
>> +  void write(ELFWriter *writer,
>>               OwningPtr<FileOutputBuffer> &buffer) {
>> -
>>      uint8_t *chunkBuffer = buffer->getBufferStart();
>>      uint8_t *atomContent = chunkBuffer + this->fileOffset();
>>      memcpy(atomContent, &_eh, fileSize());
>> @@ -1180,20 +1203,23 @@
>>
>>  /// \brief An ELFProgramHeader represents the Elf[32/64]_Phdr structure
>> at the
>>  ///        start of an ELF executable file.
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class ELFProgramHeader : public Chunk<target_endianness, is64Bits> {
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class ELFProgramHeader : public Chunk<target_endianness, max_align,
>> is64Bits> {
>>  public:
>> -  typedef object::Elf_Phdr<target_endianness, is64Bits> Elf_Phdr;
>> +  typedef Elf_Phdr<target_endianness, max_align, is64Bits> Elf_Phdr;
>>
>>    ELFProgramHeader()
>> -  : Chunk<target_endianness, is64Bits>("elfphdr"
>> -  , Chunk<target_endianness, is64Bits>::K_ELFProgramHeader) { }
>> +  : Chunk<target_endianness, max_align, is64Bits>(
>> +      "elfphdr",
>> +      Chunk<target_endianness, max_align, is64Bits>::K_ELFProgramHeader)
>> { }
>>
>> -  bool addSegment(Segment<target_endianness, is64Bits> *segment) {
>> +  bool addSegment(Segment<target_endianness, max_align, is64Bits>
>> *segment) {
>>      Elf_Phdr *phdr = nullptr;
>>      bool ret = false;
>>
>> -    for (auto sei = segment->slices_begin(), see = segment->slices_end();
>> +    for (auto sei = segment->slices_begin(), see = segment->slices_end();
>>                                               sei != see; ++sei) {
>>        if (_phi == _ph.end()) {
>>          phdr = new(_allocator.Allocate<Elf_Phdr>()) Elf_Phdr;
>> @@ -1211,14 +1237,14 @@
>>        phdr->p_filesz = (*sei)->fileSize();
>>        phdr->p_memsz = (*sei)->memSize();
>>        phdr->p_flags = segment->flags();
>> -      phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ?
>> +      phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ?
>>                         segment->pageSize() : (*sei)->align2();
>>      }
>>      return ret;
>>    }
>>
>>    void resetProgramHeaders() {
>> -    _phi = _ph.begin();
>> +    _phi = _ph.begin();
>>    }
>>
>>    void setVAddr(uint64_t addr) {
>> @@ -1226,15 +1252,18 @@
>>      this->_fsize = this->_start - addr;
>>    }
>>
>> -  uint64_t  fileSize() { return this->_fsize + (sizeof (Elf_Phdr) *
>> _ph.size()); }
>> +  uint64_t  fileSize() {
>> +    return this->_fsize + (sizeof (Elf_Phdr) * _ph.size());
>> +  }
>>
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->Kind() ==  Chunk<target_endianness,
>> is64Bits>::K_ELFProgramHeader;
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->Kind() ==
>> +      Chunk<target_endianness, max_align, is64Bits>::K_ELFProgramHeader;
>>    }
>>
>> -  void write(ELFWriter *writer,
>> +  void write(ELFWriter *writer,
>>               OwningPtr<FileOutputBuffer> &buffer) {
>> -
>>      uint8_t *chunkBuffer = buffer->getBufferStart();
>>      uint8_t *dest = chunkBuffer + this->fileOffset();
>>      for (auto phi : _ph) {
>> @@ -1245,7 +1274,7 @@
>>
>>    void finalize() { }
>>
>> -  int64_t entsize() {
>> +  int64_t entsize() {
>>      return sizeof(Elf_Phdr);
>>    }
>>
>> @@ -1262,14 +1291,17 @@
>>
>>  /// \brief An ELFSectionHeader represents the Elf[32/64]_Shdr structure
>>  /// at the end of the file
>> -template<support::endianness target_endianness, bool is64Bits>
>> -class ELFSectionHeader : public Chunk<target_endianness, is64Bits> {
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +class ELFSectionHeader : public Chunk<target_endianness, max_align,
>> is64Bits> {
>>  public:
>> -  typedef object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
>> +  typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;
>>
>> -  ELFSectionHeader(int32_t order):Chunk<target_endianness,
>> is64Bits>("shdr",
>> -                                 Chunk<target_endianness,
>> is64Bits>::K_ELFSectionHeader)
>> -  {
>> +  ELFSectionHeader(int32_t order)
>> +    : Chunk<target_endianness, max_align, is64Bits>(
>> +        "shdr",
>> +        Chunk<target_endianness, max_align,
>> is64Bits>::K_ELFSectionHeader) {
>>      this->_fsize = 0;
>>      this->_align2 = 8;
>>      this->setOrder(order);
>> @@ -1280,11 +1312,12 @@
>>      this->_fsize += sizeof (Elf_Shdr);
>>    }
>>
>> -  uint16_t fileSize() {
>> +  uint16_t fileSize() {
>>      return sizeof(Elf_Shdr) * _sectionInfo.size();
>>    }
>>
>> -  void appendSection(MergedSections<target_endianness, is64Bits>
>> *section) {
>> +  void appendSection(
>> +      MergedSections<target_endianness, max_align, is64Bits> *section) {
>>      Elf_Shdr *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>())
>> Elf_Shdr;
>>      shdr->sh_name   = _stringSection->addString(section->name());
>>      shdr->sh_type   = section->type();
>> @@ -1299,7 +1332,7 @@
>>      _sectionInfo.push_back(shdr);
>>    }
>>
>> -  void updateSection(Section<target_endianness, is64Bits> *section) {
>> +  void updateSection(Section<target_endianness, max_align, is64Bits>
>> *section) {
>>      Elf_Shdr *shdr = _sectionInfo[section->ordinal()];
>>      shdr->sh_type   = section->type();
>>      shdr->sh_flags  = section->flags();
>> @@ -1312,17 +1345,19 @@
>>      shdr->sh_entsize = section->entsize();
>>    }
>>
>> -  static inline bool classof(const Chunk<target_endianness, is64Bits> *c)
>> {
>> -    return c->getChunkKind() ==  Chunk<target_endianness,
>> is64Bits>::K_ELFSectionHeader;
>> +  static inline bool classof(
>> +      const Chunk<target_endianness, max_align, is64Bits> *c) {
>> +    return c->getChunkKind() ==
>> +      Chunk<target_endianness, max_align, is64Bits>::K_ELFSectionHeader;
>>    }
>>
>> -  void setStringSection(ELFStringTable<target_endianness, is64Bits> *s) {
>> +  void setStringSection(
>> +      ELFStringTable<target_endianness, max_align, is64Bits> *s) {
>>      _stringSection = s;
>>    }
>>
>> -  void write(ELFWriter *writer,
>> +  void write(ELFWriter *writer,
>>               OwningPtr<FileOutputBuffer> &buffer) {
>> -
>>      uint8_t *chunkBuffer = buffer->getBufferStart();
>>      uint8_t *dest = chunkBuffer + this->fileOffset();
>>      for (auto shi : _sectionInfo) {
>> @@ -1334,7 +1369,7 @@
>>
>>    void finalize() { }
>>
>> -  int64_t entsize() {
>> +  int64_t entsize() {
>>      return sizeof(Elf_Shdr);
>>    }
>>
>> @@ -1343,23 +1378,24 @@
>>    }
>>
>>  private:
>> -  ELFStringTable<target_endianness, is64Bits> *_stringSection;
>> +  ELFStringTable<target_endianness, max_align, is64Bits> *_stringSection;
>>    std::vector<Elf_Shdr*>                  _sectionInfo;
>>    llvm::BumpPtrAllocator                  _sectionAllocate;
>>  };
>>
>> -
>> -/// \brief The DefaultELFLayout class is used by the Writer to arrange
>> -///        sections and segments in the order determined by the target
>> ELF
>> +/// \brief The DefaultELFLayout class is used by the Writer to arrange
>> +///        sections and segments in the order determined by the target
>> ELF
>>  ///        format. The writer creates a single instance of the
>> DefaultELFLayout
>> -///        class
>> -template<support::endianness target_endianness, bool is64Bits>
>> +///        class
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class DefaultELFLayout : public ELFLayout {
>>  public:
>>
>>    // The order in which the sections appear in the output file
>> -  // If its determined, that the layout needs to change
>> -  // just changing the order of enumerations would essentially
>> +  // If its determined, that the layout needs to change
>> +  // just changing the order of enumerations would essentially
>>    // change the layout in the output file
>>    enum DefaultSectionOrder {
>>      ORDER_NOT_DEFINED = 0,
>> @@ -1392,22 +1428,22 @@
>>  public:
>>
>>    // The Key used for creating Sections
>> -  // The sections are created using
>> +  // The sections are created using
>>    // SectionName, [contentType, contentPermissions]
>> -  typedef std::pair<StringRef,
>> +  typedef std::pair<StringRef,
>>                      std::pair<int32_t, int32_t>> Key;
>> -  typedef typename std::vector<Chunk<target_endianness, is64Bits>
>> *>::iterator
>> -
>> ChunkIter;
>> +  typedef typename std::vector<
>> +    Chunk<target_endianness, max_align, is64Bits> *>::iterator ChunkIter;
>>    // The key used for Segments
>> -  // The segments are created using
>> +  // The segments are created using
>>    // SegmentName, Segment flags
>>    typedef std::pair<StringRef, int64_t> SegmentKey;
>>    // Merged Sections contain the map of Sectionnames to a vector of
>> sections,
>>    // that have been merged to form a single section
>> -  typedef std::map<StringRef, MergedSections<target_endianness, is64Bits>
>> *>
>> -
>> MergedSectionMapT;
>> -  typedef typename std::vector
>> -   <MergedSections<target_endianness, is64Bits> *>::iterator
>> MergedSectionIter;
>> +  typedef std::map<StringRef, MergedSections<
>> +    target_endianness, max_align, is64Bits> *> MergedSectionMapT;
>> +  typedef typename std::vector<MergedSections<
>> +    target_endianness, max_align, is64Bits> *>::iterator
>> MergedSectionIter;
>>
>>    // HashKey for the Section
>>    class HashKey {
>> @@ -1429,10 +1465,10 @@
>>      }
>>    };
>>
>> -  typedef std::unordered_map<Key,
>> -          Section<target_endianness, is64Bits>*, HashKey> SectionMapT;
>> +  typedef std::unordered_map<Key, Section<
>> +    target_endianness, max_align, is64Bits>*, HashKey> SectionMapT;
>>    typedef std::unordered_map<SegmentKey,
>> -                             Segment<target_endianness, is64Bits>*,
>> +                             Segment<target_endianness, max_align,
>> is64Bits>*,
>>                               SegmentHashKey> SegmentMapT;
>>
>>    DefaultELFLayout(const WriterOptionsELF &options):_options(options) { }
>> @@ -1453,19 +1489,19 @@
>>          .Default(ORDER_TEXT);
>>
>>      case DefinedAtom::typeConstant:
>> -      return ORDER_RODATA;
>> -
>> +      return ORDER_RODATA;
>> +
>>      case DefinedAtom::typeData:
>>        return ORDER_DATA;
>> -
>> +
>>      case DefinedAtom::typeZeroFill:
>>        return ORDER_BSS;
>>
>>      default:
>>        // If we get passed in a section push it to OTHER
>> -      if (contentPermissions == DefinedAtom::perm___)
>> +      if (contentPermissions == DefinedAtom::perm___)
>>          return ORDER_OTHER;
>> -
>> +
>>        return ORDER_NOT_DEFINED;
>>      }
>>    }
>> @@ -1473,18 +1509,18 @@
>>    /// \brief This maps the input sections to the output section names
>>    StringRef getSectionName(const StringRef name,
>>                             const int32_t contentType) {
>> -    if (contentType == DefinedAtom::typeZeroFill)
>> +    if (contentType == DefinedAtom::typeZeroFill)
>>        return ".bss";
>> -    if (name.startswith(".text"))
>> +    if (name.startswith(".text"))
>>        return ".text";
>> -    if (name.startswith(".rodata"))
>> +    if (name.startswith(".rodata"))
>>        return ".rodata";
>>      return name;
>>    }
>>
>>    /// \brief Gets the segment for a output section
>> -  virtual ELFLayout::SegmentType
>> getSegmentType(Section<target_endianness,
>> -                                     is64Bits> *section) const {
>> +  virtual ELFLayout::SegmentType getSegmentType(
>> +      Section<target_endianness, max_align, is64Bits> *section) const {
>>      switch(section->order()) {
>>      case ORDER_INTERP:
>>        return llvm::ELF::PT_INTERP;
>> @@ -1524,7 +1560,7 @@
>>
>>    /// \brief Returns true/false depending on whether the section has a
>> Output
>>    //         segment or not
>> -  static bool hasOutputSegment(Section<target_endianness,
>> +  static bool hasOutputSegment(Section<target_endianness, max_align,
>>                                   is64Bits> *section) {
>>      switch(section->order()) {
>>      case ORDER_INTERP:
>> @@ -1556,19 +1592,19 @@
>>    // Adds an atom to the section
>>    virtual error_code addAtom(const Atom *atom) {
>>      const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom);
>> -    const StringRef sectionName =
>> +    const StringRef sectionName =
>>                  getSectionName(definedAtom->customSectionName(),
>>                                 definedAtom->contentType());
>> -    const lld::DefinedAtom::ContentPermissions permissions =
>> +    const lld::DefinedAtom::ContentPermissions permissions =
>>                                    definedAtom->permissions();
>> -    const lld::DefinedAtom::ContentType contentType =
>> +    const lld::DefinedAtom::ContentType contentType =
>>                                    definedAtom->contentType();
>>      const Key key(sectionName, std::make_pair(contentType, permissions));
>> -    const std::pair<Key, Section<target_endianness, is64Bits> *>
>> +    const std::pair<Key, Section<target_endianness, max_align, is64Bits>
>> *>
>>                                                  currentSection(key,
>> nullptr);
>> -    std::pair<typename SectionMapT::iterator, bool>
>> +    std::pair<typename SectionMapT::iterator, bool>
>>
>> sectionInsert(_sectionMap.insert(currentSection));
>> -    Section<target_endianness, is64Bits> *section;
>> +    Section<target_endianness, max_align, is64Bits> *section;
>>      // the section is already in the map
>>      if (!sectionInsert.second) {
>>        section = sectionInsert.first->second;
>> @@ -1579,9 +1615,9 @@
>>                                       contentType,
>>                                       permissions);
>>        section = new (_allocator.Allocate
>> -                     <Section<target_endianness, is64Bits>>())
>> -                     Section<target_endianness, is64Bits>
>> -                     (sectionName, contentType,
>> +                     <Section<target_endianness, max_align, is64Bits>>())
>> +                     Section<target_endianness, max_align, is64Bits>
>> +                     (sectionName, contentType,
>>                        permissions, section_order);
>>        sectionInsert.first->second = section;
>>        section->setOrder(section_order);
>> @@ -1593,12 +1629,12 @@
>>
>>    // Merge sections with the same name into a MergedSections
>>    void mergeSimiliarSections() {
>> -    MergedSections<target_endianness, is64Bits> *mergedSection;
>> -
>> +    MergedSections<target_endianness, max_align, is64Bits>
>> *mergedSection;
>> +
>>      for (auto &si : _sections) {
>> -      const std::pair<StringRef, MergedSections<target_endianness,
>> is64Bits> *>
>> -
>> currentMergedSections(si->name(),
>> -
>> nullptr);
>> +      const std::pair<StringRef,
>> +                      MergedSections<target_endianness, max_align,
>> is64Bits> *>
>> +        currentMergedSections(si->name(), nullptr);
>>        std::pair<typename MergedSectionMapT::iterator, bool>
>>                                mergedSectionInsert
>>
>> (_mergedSectionMap.insert(currentMergedSections));
>> @@ -1606,9 +1642,9 @@
>>          mergedSection = mergedSectionInsert.first->second;
>>        }
>>        else {
>> -        mergedSection = new (_allocator.Allocate
>> -                     <MergedSections<target_endianness, is64Bits>>())
>> -                     MergedSections<target_endianness,
>> is64Bits>(si->name());
>> +        mergedSection = new (_allocator.Allocate<
>> +          MergedSections<target_endianness, max_align, is64Bits>>())
>> +          MergedSections<target_endianness, max_align,
>> is64Bits>(si->name());
>>          _mergedSections.push_back(mergedSection);
>>          mergedSectionInsert.first->second = mergedSection;
>>        }
>> @@ -1619,8 +1655,8 @@
>>    void assignSectionsToSegments() {
>>      // sort the sections by their order as defined by the layout
>>      std::stable_sort(_sections.begin(), _sections.end(),
>> -    [](Chunk<target_endianness, is64Bits> *A,
>> -       Chunk<target_endianness, is64Bits> *B) {
>> +    [](Chunk<target_endianness, max_align, is64Bits> *A,
>> +       Chunk<target_endianness, max_align, is64Bits> *B) {
>>         return A->order() < B->order();
>>      });
>>      // Merge all sections
>> @@ -1635,14 +1671,16 @@
>>        }
>>        ++ordinal;
>>      }
>> -    Section<target_endianness, is64Bits> *section;
>> -    Segment<target_endianness, is64Bits> *segment;
>> -    for (auto msi = merged_sections_begin(), mse = merged_sections_end();
>> +    Section<target_endianness, max_align, is64Bits> *section;
>> +    Segment<target_endianness, max_align, is64Bits> *segment;
>> +    for (auto msi = merged_sections_begin(), mse = merged_sections_end();
>>                                               msi != mse; ++msi) {
>> -      for (auto ai = (*msi)->begin_sections(), ae =
>> (*msi)->end_sections();
>> +      for (auto ai = (*msi)->begin_sections(), ae =
>> (*msi)->end_sections();
>>                                                 ai != ae; ++ai) {
>> -        if ((*ai)->kind() == Chunk<target_endianness,
>> is64Bits>::K_ELFSection) {
>> -          section = llvm::dyn_cast<Section<target_endianness,
>> is64Bits>>(*ai);
>> +        if ((*ai)->kind() ==
>> +              Chunk<target_endianness, max_align,
>> is64Bits>::K_ELFSection) {
>> +          section = llvm::dyn_cast<
>> +            Section<target_endianness, max_align, is64Bits>>(*ai);
>>            if (!hasOutputSegment(section))
>>              continue;
>>            (*msi)->setHasSegment();
>> @@ -1650,18 +1688,19 @@
>>            const StringRef segmentName = section->segmentKindToStr();
>>            // Use the flags of the merged Section for the segment
>>            const SegmentKey key(segmentName, (*msi)->flags());
>> -          const std::pair<SegmentKey, Segment<target_endianness,
>> is64Bits> *>
>> -                                                  currentSegment(key,
>> nullptr);
>> -          std::pair<typename SegmentMapT::iterator, bool>
>> +          const std::pair<SegmentKey,
>> +                          Segment<target_endianness, max_align, is64Bits>
>> *>
>> +            currentSegment(key, nullptr);
>> +          std::pair<typename SegmentMapT::iterator, bool>
>>
>> segmentInsert(_segmentMap.insert(currentSegment));
>>
>>            if (!segmentInsert.second) {
>>              segment = segmentInsert.first->second;
>>            } else {
>>              segment = new (_allocator.Allocate
>> -                           <Segment<target_endianness, is64Bits>>())
>> -                           Segment<target_endianness, is64Bits>
>> -                           (segmentName, getSegmentType(section),
>> +                           <Segment<target_endianness, max_align,
>> is64Bits>>())
>> +                           Segment<target_endianness, max_align,
>> is64Bits>
>> +                           (segmentName, getSegmentType(section),
>>                              _options);
>>              segmentInsert.first->second = segment;
>>              _segments.push_back(segment);
>> @@ -1672,14 +1711,14 @@
>>      }
>>    }
>>
>> -  void addSection(Chunk<target_endianness, is64Bits> *c) {
>> +  void addSection(Chunk<target_endianness, max_align, is64Bits> *c) {
>>      _sections.push_back(c);
>>    }
>>
>>    void assignFileOffsets() {
>> -    std::sort(_segments.begin(),
>> -              _segments.end(),
>> -              Segment<target_endianness, is64Bits>::compareSegments);
>> +    std::sort(_segments.begin(),
>> +              _segments.end(),
>> +              Segment<target_endianness, max_align,
>> is64Bits>::compareSegments);
>>      int ordinal = 0;
>>      // Compute the number of segments that might be needed, so that the
>>      // size of the program header can be computed
>> @@ -1691,11 +1730,12 @@
>>      }
>>    }
>>
>> -  void setELFHeader(ELFHeader<target_endianness, is64Bits> *e) {
>> +  void setELFHeader(ELFHeader<target_endianness, max_align, is64Bits> *e)
>> {
>>      _elfHeader = e;
>>    }
>>
>> -  void setProgramHeader(ELFProgramHeader<target_endianness, is64Bits> *p)
>> {
>> +  void setProgramHeader(
>> +      ELFProgramHeader<target_endianness, max_align, is64Bits> *p) {
>>      _programHeader = p;
>>    }
>>
>> @@ -1710,7 +1750,8 @@
>>      }
>>      // Add the program header
>>      if (_programHeader) {
>> -      _programHeader->setVAddr(uint64_t(virtualAddress +
>> _elfHeader->fileSize()));
>> +      _programHeader->setVAddr(
>> +        uint64_t(virtualAddress + _elfHeader->fileSize()));
>>        _programHeader->setFileOffset(_elfHeader->fileSize());
>>      }
>>      bool newSegmentHeaderAdded = true;
>> @@ -1719,7 +1760,7 @@
>>          newSegmentHeaderAdded = _programHeader->addSegment(si);
>>          numSlices += si->numSlices();
>>        }
>> -      if (!newSegmentHeaderAdded)
>> +      if (!newSegmentHeaderAdded)
>>          break;
>>        uint64_t fileoffset = _elfHeader->fileSize() +
>> _programHeader->fileSize();
>>        uint64_t address = virtualAddress;
>> @@ -1735,29 +1776,32 @@
>>          (*si)->setVAddr(virtualAddress);
>>          // The first segment has the virtualAddress set to the base
>> address as
>>          // we have added the file header and the program header dont
>> align the
>> -        // first segment to the pagesize
>> +        // first segment to the pagesize
>>          (*si)->assignVirtualAddress(address, (si == _segments.begin()));
>>          (*si)->setMemSize(address - virtualAddress);
>>          virtualAddress = llvm::RoundUpToAlignment(address,
>> _options.pageSize());
>>        }
>>        _programHeader->resetProgramHeaders();
>>      }
>> -    Section<target_endianness, is64Bits> *section;
>> +    Section<target_endianness, max_align, is64Bits> *section;
>>      // Fix the offsets of all the atoms within a section
>>      for (auto &si : _sections) {
>> -      section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(si);
>> -      if (section &&
>> -          DefaultELFLayout<target_endianness,
>> is64Bits>::hasOutputSegment(section))
>> +      section =
>> +        llvm::dyn_cast<Section<target_endianness, max_align,
>> is64Bits>>(si);
>> +      if (section &&
>> +          DefaultELFLayout<target_endianness,
>> +                           max_align,
>> is64Bits>::hasOutputSegment(section))
>>          section->assignOffsets(section->fileOffset());
>>      }
>>      // Set the size of the merged Sections
>> -    for (auto msi = merged_sections_begin(), mse = merged_sections_end();
>> +    for (auto msi = merged_sections_begin(), mse = merged_sections_end();
>>                                               msi != mse; ++msi) {
>>        uint64_t sectionfileoffset = 0;
>>        uint64_t startFileOffset = 0;
>>        uint64_t sectionsize = 0;
>>        bool isFirstSection = true;
>> -      for (auto si = (*msi)->begin_sections(); si !=
>> (*msi)->end_sections(); ++si) {
>> +      for (auto si = (*msi)->begin_sections(); si !=
>> (*msi)->end_sections();
>> +                                               ++si) {
>>          if (isFirstSection) {
>>            startFileOffset = (*si)->fileOffset();
>>            isFirstSection = false;
>> @@ -1770,13 +1814,13 @@
>>        (*msi)->setSize(sectionsize);
>>      }
>>      // Set the virtual addr of the merged Sections
>> -    for (auto msi = merged_sections_begin(), mse = merged_sections_end();
>> +    for (auto msi = merged_sections_begin(), mse = merged_sections_end();
>>                                               msi != mse; ++msi) {
>>        uint64_t sectionstartaddr = 0;
>>        uint64_t startaddr = 0;
>>        uint64_t sectionsize = 0;
>>        bool isFirstSection = true;
>> -      for (auto si = (*msi)->begin_sections(), se =
>> (*msi)->end_sections();
>> +      for (auto si = (*msi)->begin_sections(), se =
>> (*msi)->end_sections();
>>                                                 si != se; ++si) {
>>          if (isFirstSection) {
>>            startaddr = (*si)->virtualAddr();
>> @@ -1799,12 +1843,13 @@
>>        size = si->fileSize();
>>      }
>>      fileoffset = fileoffset + size;
>> -    Section<target_endianness, is64Bits> *section;
>> +    Section<target_endianness, max_align, is64Bits> *section;
>>      for (auto si : _sections) {
>> -      section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(si);
>> -      if (section &&
>> -          DefaultELFLayout<target_endianness, is64Bits>::hasOutputSegment
>> -                                                         (section))
>> +      section =
>> +        llvm::dyn_cast<Section<target_endianness, max_align,
>> is64Bits>>(si);
>> +      if (section &&
>> +          DefaultELFLayout<target_endianness,
>> +                           max_align,
>> is64Bits>::hasOutputSegment(section))
>>          continue;
>>        fileoffset = llvm::RoundUpToAlignment(fileoffset, si->align2());
>>        si->setFileOffset(fileoffset);
>> @@ -1820,22 +1865,24 @@
>>    }
>>
>>    bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
>> -    Section<target_endianness, is64Bits> *section;
>> +    Section<target_endianness, max_align, is64Bits> *section;
>>      for (auto ai = _sections.begin(); ai != _sections.end(); ++ai) {
>> -      if ((*ai)->kind() == Chunk<target_endianness,
>> is64Bits>::K_ELFSection) {
>> -        section = llvm::dyn_cast<Section<target_endianness,
>> is64Bits>>(*ai);
>> +      if ((*ai)->kind() ==
>> +            Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)
>> {
>> +        section =
>> +          llvm::dyn_cast<Section<target_endianness, max_align,
>> is64Bits>>(*ai);
>>          if (section->findAtomAddrByName(name, addr))
>>           return true;
>>        }
>>      }
>> -    return false;
>> +    return false;
>>    }
>>
>> -  MergedSectionIter merged_sections_begin() {
>> +  MergedSectionIter merged_sections_begin() {
>>      return _mergedSections.begin();
>>    }
>>
>> -  MergedSectionIter merged_sections_end() {
>> +  MergedSectionIter merged_sections_end() {
>>      return _mergedSections.end();
>>    }
>>
>> @@ -1854,11 +1901,11 @@
>>      return _segments.end();
>>    }
>>
>> -  ELFHeader<target_endianness, is64Bits> *elfHeader() {
>> +  ELFHeader<target_endianness, max_align, is64Bits> *elfHeader() {
>>      return _elfHeader;
>>    }
>>
>> -  ELFProgramHeader<target_endianness, is64Bits> *elfProgramHeader() {
>> +  ELFProgramHeader<target_endianness, max_align, is64Bits>
>> *elfProgramHeader() {
>>      return _programHeader;
>>    }
>>
>> @@ -1867,11 +1914,12 @@
>>    MergedSectionMapT _mergedSectionMap;
>>    SegmentMapT _segmentMap;
>>
>> -  std::vector<Chunk<target_endianness, is64Bits> *> _sections;
>> -  std::vector<Segment<target_endianness, is64Bits> *> _segments;
>> -  std::vector<MergedSections<target_endianness, is64Bits> *>
>> _mergedSections;
>> -  ELFHeader<target_endianness, is64Bits> *_elfHeader;
>> -  ELFProgramHeader<target_endianness, is64Bits> *_programHeader;
>> +  std::vector<Chunk<target_endianness, max_align, is64Bits> *> _sections;
>> +  std::vector<Segment<target_endianness, max_align, is64Bits> *>
>> _segments;
>> +  std::vector<MergedSections<target_endianness, max_align, is64Bits> *>
>> +    _mergedSections;
>> +  ELFHeader<target_endianness, max_align, is64Bits> *_elfHeader;
>> +  ELFProgramHeader<target_endianness, max_align, is64Bits>
>> *_programHeader;
>>    llvm::BumpPtrAllocator _allocator;
>>    const WriterOptionsELF &_options;
>>  };
>> @@ -1879,16 +1927,18 @@
>>
>> //===----------------------------------------------------------------------===//
>>  //  ELFExecutableWriter Class
>>
>> //===----------------------------------------------------------------------===//
>> -template<support::endianness target_endianness, bool is64Bits>
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>>  class ELFExecutableWriter : public ELFWriter {
>>  public:
>> -  typedef object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
>> -  typedef object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
>> +  typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;
>> +  typedef Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;
>>
>>    ELFExecutableWriter(const WriterOptionsELF &options);
>>
>>  private:
>> -  // build the sections that need to be created
>> +  // build the sections that need to be created
>>    void buildChunks(const lld::File &file);
>>    virtual error_code writeFile(const lld::File &File, StringRef path);
>>    void buildAtomToAddressMap();
>> @@ -1897,7 +1947,7 @@
>>    void assignSectionsWithNoSegments();
>>    void addAbsoluteUndefinedSymbols(const lld::File &File);
>>
>> -  uint64_t addressOfAtom(const Atom *atom) {
>> +  uint64_t addressOfAtom(const Atom *atom) {
>>      return _atomToAddressMap[atom];
>>    }
>>
>> @@ -1911,114 +1961,140 @@
>>    std::unique_ptr<KindHandler> _referenceKindHandler;
>>    AtomToAddress _atomToAddressMap;
>>    llvm::BumpPtrAllocator _chunkAllocate;
>> -  DefaultELFLayout<target_endianness, is64Bits> *_layout;
>> -  ELFHeader<target_endianness, is64Bits> *_elfHeader;
>> -  ELFProgramHeader<target_endianness, is64Bits> *_programHeader;
>> -  ELFSymbolTable<target_endianness, is64Bits> * _symtab;
>> -  ELFStringTable<target_endianness, is64Bits> *_strtab;
>> -  ELFStringTable<target_endianness, is64Bits> *_shstrtab;
>> -  ELFSectionHeader<target_endianness, is64Bits> *_shdrtab;
>> +  DefaultELFLayout<target_endianness, max_align, is64Bits> *_layout;
>> +  ELFHeader<target_endianness, max_align, is64Bits> *_elfHeader;
>> +  ELFProgramHeader<target_endianness, max_align, is64Bits>
>> *_programHeader;
>> +  ELFSymbolTable<target_endianness, max_align, is64Bits> * _symtab;
>> +  ELFStringTable<target_endianness, max_align, is64Bits> *_strtab;
>> +  ELFStringTable<target_endianness, max_align, is64Bits> *_shstrtab;
>> +  ELFSectionHeader<target_endianness, max_align, is64Bits> *_shdrtab;
>>  };
>>
>>
>> //===----------------------------------------------------------------------===//
>>  //  ELFExecutableWriter
>>
>> //===----------------------------------------------------------------------===//
>> -template<support::endianness target_endianness, bool is64Bits>
>> -ELFExecutableWriter<target_endianness, is64Bits>
>> -         ::ELFExecutableWriter(const WriterOptionsELF &options)
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +ELFExecutableWriter<target_endianness, max_align, is64Bits>
>> +                   ::ELFExecutableWriter(const WriterOptionsELF &options)
>>    : _options(options)
>>    , _referenceKindHandler(KindHandler::makeHandler(_options.machine(),
>> -                                                   target_endianness))
>> -{
>> -  _layout = new DefaultELFLayout<target_endianness, is64Bits>(options);
>> +                                                   target_endianness)) {
>> +  _layout =
>> +    new DefaultELFLayout<target_endianness, max_align,
>> is64Bits>(options);
>>  }
>>
>> -template<support::endianness target_endianness, bool is64Bits>
>> -void ELFExecutableWriter<target_endianness, is64Bits>
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
>>                          ::buildChunks(const lld::File &file){
>>    for (const DefinedAtom *definedAtom : file.defined() ) {
>>      _layout->addAtom(definedAtom);
>>    }
>>  }
>>
>> -template<support::endianness target_endianness, bool is64Bits>
>> -void ELFExecutableWriter<target_endianness, is64Bits>::buildSymbolTable
>> () {
>> -  Section<target_endianness, is64Bits> *section;
>> -  for (auto si = _layout->sections_begin(); si !=
>> _layout->sections_end(); ++si) {
>> -    if ((*si)->kind() != Chunk<target_endianness,
>> is64Bits>::K_ELFSection)
>> +template<support::endianness target_endianness,
>> +         std::size_t max_align,
>> +         bool is64Bits>
>> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
>> +                        ::buildSymbolTable () {
>> +  Section<target_endianness, max_align, is64Bits> *section;
>> +  for (auto si = _layout->sections_begin(); si !=
>> _layout->sections_end();
>> +                                            ++si) {
>> +    if ((*si)->kind() !=
>> +          Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)
>>        continue;
>> -    section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*si);
>> +    section =
>> +      llvm::dyn_cast<Section<target_endianness, max_align,
>> is64Bits>>(*si);
>>      for (auto ai = section->atoms_begin(); ai != section->atoms_end();
>> ++ai) {
>>        _symtab->addSymbol(ai->
>
> ...
>
> [Message clipped]



More information about the llvm-commits mailing list