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

Chandler Carruth chandlerc at google.com
Fri Jan 4 13:24:00 PST 2013


Tests?


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->first, section->ordinal(),
> ai->second.second);
>      }
>    }
>  }
>
> -template<support::endianness target_endianness, bool is64Bits>
> -void ELFExecutableWriter<target_endianness, is64Bits>::
> -                addAbsoluteUndefinedSymbols(const lld::File &file) {
> +template<support::endianness target_endianness,
> +         std::size_t max_align,
> +         bool is64Bits>
> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
> +                        ::addAbsoluteUndefinedSymbols(const lld::File
> &file) {
>   for (const UndefinedAtom *a : file.undefined()) {
>     _symtab->addSymbol(a, ELF::SHN_UNDEF);
>   }
> -
> +
>   for (const AbsoluteAtom *a : file.absolute()) {
>     _symtab->addSymbol(a, ELF::SHN_ABS);
>   }
>  }
>
> -template<support::endianness target_endianness, bool is64Bits>
> -void ELFExecutableWriter<target_endianness, is64Bits>
> -              ::buildAtomToAddressMap () {
> -  Section<target_endianness, is64Bits> *section;
> -  for (auto si = _layout->sections_begin();
> +template<support::endianness target_endianness,
> +         std::size_t max_align,
> +         bool is64Bits>
> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
> +                        ::buildAtomToAddressMap () {
> +  Section<target_endianness, max_align, is64Bits> *section;
> +  for (auto si = _layout->sections_begin();
>         si != _layout->sections_end(); ++si) {
> -    if ((*si)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)
> +    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) {
>        _atomToAddressMap[ai->first] = (ai)->second.second;
>      }
>    }
>  }
>
> -template<support::endianness target_endianness, bool is64Bits>
> -void ELFExecutableWriter<target_endianness, is64Bits>
> -              ::buildSectionHeaderTable() {
> -  for (auto msi = _layout->merged_sections_begin();
> +template<support::endianness target_endianness,
> +         std::size_t max_align,
> +         bool is64Bits>
> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
> +                        ::buildSectionHeaderTable() {
> +  for (auto msi = _layout->merged_sections_begin();
>         msi != _layout->merged_sections_end(); ++msi) {
> -    if ((*msi)->kind() != Chunk<target_endianness,
> is64Bits>::K_ELFSection)
> +    if ((*msi)->kind() !=
> +          Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)
>        continue;
>      if ((*msi)->hasSegment())
>        _shdrtab->appendSection(*msi);
>    }
>  }
>
> -template<support::endianness target_endianness, bool is64Bits>
> -void ELFExecutableWriter<target_endianness, is64Bits>
> -              ::assignSectionsWithNoSegments() {
> -  Section<target_endianness, is64Bits> *section;
> -  for (auto msi = _layout->merged_sections_begin();
> +template<support::endianness target_endianness,
> +         std::size_t max_align,
> +         bool is64Bits>
> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
> +                        ::assignSectionsWithNoSegments() {
> +  Section<target_endianness, max_align, is64Bits> *section;
> +  for (auto msi = _layout->merged_sections_begin();
>         msi != _layout->merged_sections_end(); ++msi) {
> -    if ((*msi)->kind() != Chunk<target_endianness,
> is64Bits>::K_ELFSection)
> +    if ((*msi)->kind() !=
> +          Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)
>        continue;
>      if (!(*msi)->hasSegment())
>        _shdrtab->appendSection(*msi);
>    }
>    _layout->assignOffsetsForMiscSections();
> -  for (auto si = _layout->sections_begin();
> +  for (auto si = _layout->sections_begin();
>         si != _layout->sections_end(); ++si) {
> -    if ((*si)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)
> +    if ((*si)->kind() !=
> +          Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)
>        continue;
> -    section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*si);
> -    if (!DefaultELFLayout<target_endianness, is64Bits>::hasOutputSegment
> -                                                        (section))
> +    section =
> +      llvm::dyn_cast<Section<target_endianness, max_align,
> is64Bits>>(*si);
> +    if (!DefaultELFLayout<target_endianness, max_align, is64Bits>
> +                         ::hasOutputSegment(section))
>        _shdrtab->updateSection(section);
>    }
>  }
>
> -template<support::endianness target_endianness, bool is64Bits>
> -error_code ELFExecutableWriter<target_endianness, is64Bits>
> -                    ::writeFile(const lld::File &file, StringRef path) {
> +template<support::endianness target_endianness,
> +         std::size_t max_align,
> +         bool is64Bits>
> +error_code ELFExecutableWriter<target_endianness, max_align, is64Bits>
> +                            ::writeFile(const lld::File &file, StringRef
> path) {
>    buildChunks(file);
>    // Create the default sections like the symbol table, string table, and
> the
>    // section string table
> @@ -2062,7 +2138,7 @@
>
>    _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64
>                                                          :
> ELF::ELFCLASS32));
> -  _elfHeader->e_ident(ELF::EI_DATA, (_options.endianness() ==
> llvm::support::big)
> +  _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() ==
> llvm::support::big
>                                      ? ELF::ELFDATA2MSB :
> ELF::ELFDATA2LSB);
>    _elfHeader->e_ident(ELF::EI_VERSION, 1);
>    _elfHeader->e_ident(ELF::EI_OSABI, 0);
> @@ -2086,25 +2162,33 @@
>    return buffer->commit();
>  }
>
> -template<support::endianness target_endianness, bool is64Bits>
> -void ELFExecutableWriter<target_endianness, is64Bits>
> -                    ::createDefaultSections() {
> -  _elfHeader = new ELFHeader<target_endianness, is64Bits>();
> -  _programHeader = new ELFProgramHeader<target_endianness, is64Bits>();
> +template<support::endianness target_endianness,
> +         std::size_t max_align,
> +         bool is64Bits>
> +void ELFExecutableWriter<target_endianness, max_align, is64Bits>
> +                        ::createDefaultSections() {
> +  _elfHeader =
> +    new ELFHeader<target_endianness, max_align, is64Bits>();
> +  _programHeader =
> +    new ELFProgramHeader<target_endianness, max_align, is64Bits>();
>    _layout->setELFHeader(_elfHeader);
>    _layout->setProgramHeader(_programHeader);
>
> -  _symtab = new ELFSymbolTable<target_endianness, is64Bits>
> -            (".symtab",
> -            DefaultELFLayout<target_endianness,
> is64Bits>::ORDER_SYMBOL_TABLE);
> -  _strtab = new ELFStringTable<target_endianness, is64Bits>
> -          (".strtab",
> -          DefaultELFLayout<target_endianness,
> is64Bits>::ORDER_STRING_TABLE);
> -  _shstrtab = new ELFStringTable<target_endianness, is64Bits>
> -          (".shstrtab",
> -          DefaultELFLayout<target_endianness,
> is64Bits>::ORDER_SECTION_STRINGS);
> -  _shdrtab  = new ELFSectionHeader<target_endianness, is64Bits>
> -         (DefaultELFLayout<target_endianness,
> is64Bits>::ORDER_SECTION_HEADERS);
> +  _symtab = new ELFSymbolTable<target_endianness, max_align, is64Bits>(
> +    ".symtab",
> +    DefaultELFLayout<target_endianness, max_align, is64Bits>
> +                    ::ORDER_SYMBOL_TABLE);
> +  _strtab = new ELFStringTable<target_endianness, max_align, is64Bits>(
> +    ".strtab",
> +    DefaultELFLayout<target_endianness, max_align, is64Bits>
> +                    ::ORDER_STRING_TABLE);
> +  _shstrtab = new ELFStringTable<target_endianness, max_align, is64Bits>(
> +    ".shstrtab",
> +    DefaultELFLayout<target_endianness, max_align, is64Bits>
> +                    ::ORDER_SECTION_STRINGS);
> +  _shdrtab  = new ELFSectionHeader<target_endianness, max_align,
> is64Bits>(
> +    DefaultELFLayout<target_endianness, max_align, is64Bits>
> +                    ::ORDER_SECTION_HEADERS);
>    _layout->addSection(_symtab);
>    _layout->addSection(_strtab);
>    _layout->addSection(_shstrtab);
> @@ -2112,23 +2196,21 @@
>    _symtab->setStringSection(_strtab);
>    _layout->addSection(_shdrtab);
>  }
> -
>  } // namespace elf
>
>  Writer *createWriterELF(const WriterOptionsELF &options) {
> -
>    // Set the default layout to be the static executable layout
> -  // We would set the layout to a dynamic executable layout
> +  // We would set the layout to a dynamic executable layout
>    // if we came across any shared libraries in the process
> -
> +
>    if (!options.is64Bit() && options.endianness() == llvm::support::little)
> -    return new lld::elf::ELFExecutableWriter<support::little,
> false>(options);
> +    return new elf::ELFExecutableWriter<support::little, 4,
> false>(options);
>    else if (options.is64Bit() && options.endianness() ==
> llvm::support::little)
> -    return new lld::elf::ELFExecutableWriter<support::little,
> true>(options);
> +    return new elf::ELFExecutableWriter<support::little, 8,
> true>(options);
>    else if (!options.is64Bit() && options.endianness() ==
> llvm::support::big)
> -    return new lld::elf::ELFExecutableWriter<support::big,
> false>(options);
> +    return new elf::ELFExecutableWriter<support::big, 4, false>(options);
>    else if (options.is64Bit() && options.endianness() ==
> llvm::support::big)
> -    return new lld::elf::ELFExecutableWriter<support::big, true>(options);
> +    return new elf::ELFExecutableWriter<support::big, 8, true>(options);
>
>    llvm_unreachable("Invalid Options!");
>  }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130104/ed219a05/attachment.html>


More information about the llvm-commits mailing list