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

Michael J. Spencer bigcheesegs at gmail.com
Fri Jan 4 13:09:21 PST 2013


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!");
 }





More information about the llvm-commits mailing list