add targethandler hooks from Writer and cleanup
authorShankar Easwaran <shankare@codeaurora.org>
Wed, 30 Jan 2013 07:11:43 +0000 (07:11 +0000)
committerShankar Easwaran <shankare@codeaurora.org>
Wed, 30 Jan 2013 07:11:43 +0000 (07:11 +0000)
llvm-svn: 173904

lld/lib/ReaderWriter/ELF/Chunk.h
lld/lib/ReaderWriter/ELF/DefaultLayout.h
lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
lld/lib/ReaderWriter/ELF/File.h
lld/lib/ReaderWriter/ELF/SectionChunks.h
lld/lib/ReaderWriter/ELF/SegmentChunks.h
lld/lib/ReaderWriter/ELF/TargetHandler.h
lld/lib/ReaderWriter/ELF/TargetLayout.h
lld/lib/ReaderWriter/ELF/Writer.cpp

index 801896e..f815c84 100644 (file)
@@ -44,11 +44,9 @@ public:
       : _name(name), _kind(kind), _fsize(0), _msize(0), _align2(0), _order(0),
         _ordinal(1), _start(0), _fileoffset(0), _targetInfo(ti) {
   }
-  virtual             ~Chunk() {}
+  virtual ~Chunk() {}
   // Does the chunk occupy disk space
-  virtual bool        occupiesNoDiskSpace() const {
-    return false;
-  }
+  virtual bool occupiesNoDiskSpace() const { return false; }
   // The name of the chunk
   StringRef name() const { return _name; }
   // Kind of chunk
@@ -74,7 +72,7 @@ public:
   // Writer the chunk
   virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0;
   // Finalize the chunk before writing
-  virtual void       finalize() = 0;
+  virtual void finalize() = 0;
 
 protected:
   StringRef _name;
index c6dcfde..035600a 100644 (file)
@@ -90,7 +90,7 @@ public:
     }
 
     // Data members
-    const StringRef _name;
+    StringRef _name;
     DefinedAtom::ContentPermissions _perm;
   };
 
@@ -141,17 +141,22 @@ public:
 
   typedef typename std::vector<AtomLayout *>::iterator AbsoluteAtomIterT;
 
-  DefaultLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
+  DefaultLayout(const ELFTargetInfo &ti)
+      : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()) {
+  }
 
   /// \brief Return the section order for a input section
-  virtual SectionOrder getSectionOrder
-              (const StringRef name,
-              int32_t contentType,
-              int32_t contentPermissions);
+  virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType,
+                                       int32_t contentPermissions);
 
   /// \brief This maps the input sections to the output section names
-  StringRef getSectionName(const StringRef name,
-                           const int32_t contentType);
+  virtual StringRef getSectionName(StringRef name, const int32_t contentType,
+                                   const int32_t contentPermissions);
+
+  /// \brief Returns the section to be created
+  virtual Section<ELFT> *getSection(StringRef name, const int32_t contentType,
+                                    const int32_t contentPermissions,
+                                    const int32_t sectionOrder);
 
   /// \brief Gets the segment for a output section
   virtual Layout::SegmentType getSegmentType(Section<ELFT> *section) const;
@@ -172,9 +177,9 @@ public:
   }
 
   /// \brief find a absolute atom given a name
-  AbsoluteAtomIterT findAbsoluteAtom(const StringRef name) {
+  AbsoluteAtomIterT findAbsoluteAtom(StringRef name) {
     return std::find_if(_absoluteAtoms.begin(), _absoluteAtoms.end(),
-                                                FindByName(name));
+                        FindByName(name));
   }
 
   // Merge sections with the same name into a MergedSections
@@ -200,9 +205,9 @@ public:
       si->finalize();
   }
 
-  inline bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
+  inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
     for (auto sec : _sections)
-      if (auto section = dyn_cast<Section<ELFT>>(sec))
+      if (auto section = dyn_cast<Section<ELFT> >(sec))
         if (section->findAtomAddrByName(name, addr))
          return true;
     return false;
@@ -253,14 +258,12 @@ private:
   std::vector<AtomLayout *> _absoluteAtoms;
   llvm::BumpPtrAllocator _allocator;
   const ELFTargetInfo &_targetInfo;
+  TargetHandler<ELFT> &_targetHandler;
 };
 
-template<class ELFT>
-Layout::SectionOrder
-DefaultLayout<ELFT>::getSectionOrder(const StringRef name, 
-                                        int32_t contentType,
-                                        int32_t contentPermissions)
-{
+template <class ELFT>
+Layout::SectionOrder DefaultLayout<ELFT>::getSectionOrder(
+    StringRef name, int32_t contentType, int32_t contentPermissions) {
   switch (contentType) {
   case DefinedAtom::typeResolver:
   case DefinedAtom::typeCode:
@@ -298,10 +301,10 @@ DefaultLayout<ELFT>::getSectionOrder(const StringRef name,
 }
 
 /// \brief This maps the input sections to the output section names
-template<class ELFT>
-StringRef 
-DefaultLayout<ELFT>::getSectionName(const StringRef name, 
-                                       const int32_t contentType) {
+template <class ELFT>
+StringRef DefaultLayout<ELFT>::getSectionName(
+    StringRef name, const int32_t contentType,
+    const int32_t contentPermissions) {
   if (contentType == DefinedAtom::typeZeroFill)
     return ".bss";
   if (name.startswith(".text"))
@@ -312,10 +315,11 @@ DefaultLayout<ELFT>::getSectionName(const StringRef name,
 }
 
 /// \brief Gets the segment for a output section
-template<class ELFT>
-Layout::SegmentType 
-DefaultLayout<ELFT>::getSegmentType(Section<ELFT> *section) const {
-  switch(section->order()) {
+template <class ELFT>
+Layout::SegmentType DefaultLayout<ELFT>::getSegmentType(
+    Section<ELFT> *section) const {
+
+  switch (section->order()) {
   case ORDER_INTERP:
     return llvm::ELF::PT_INTERP;
 
@@ -355,10 +359,12 @@ DefaultLayout<ELFT>::getSegmentType(Section<ELFT> *section) const {
   }
 }
 
-template<class ELFT>
-bool
-DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
-  switch(section->order()) {
+template <class ELFT>
+bool DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
+  if (section->sectionKind() == Section<ELFT>::K_Target)
+    return section->hasOutputSegment();
+
+  switch (section->order()) {
   case ORDER_INTERP:
   case ORDER_HASH:
   case ORDER_DYNAMIC_SYMBOLS:
@@ -389,6 +395,14 @@ DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
 }
 
 template <class ELFT>
+Section<ELFT> *DefaultLayout<ELFT>::getSection(
+    StringRef sectionName, int32_t contentType, int32_t permissions,
+    int32_t sectionOrder) {
+  return new (_allocator) Section<ELFT>(_targetInfo, sectionName, contentType,
+                                        permissions, sectionOrder);
+}
+
+template <class ELFT>
 ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
   if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
     // HACK: Ignore undefined atoms. We need to adjust the interface so that
@@ -396,20 +410,21 @@ ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
     // -noinhibit-exec.
     if (definedAtom->contentType() == DefinedAtom::typeUnknown)
       return make_error_code(llvm::errc::invalid_argument);
-    const StringRef sectionName = getSectionName(
-        definedAtom->customSectionName(), definedAtom->contentType());
+    StringRef sectionName = definedAtom->customSectionName();
     const DefinedAtom::ContentPermissions permissions =
         definedAtom->permissions();
-    const DefinedAtom::ContentType contentType =
-        definedAtom->contentType();
+    const DefinedAtom::ContentType contentType = definedAtom->contentType();
+
+    sectionName = getSectionName(sectionName, contentType, permissions);
+
     const SectionKey sectionKey(sectionName, permissions);
     Section<ELFT> *section;
 
     if (_sectionMap.find(sectionKey) == _sectionMap.end()) {
       SectionOrder section_order =
           getSectionOrder(sectionName, contentType, permissions);
-      section = new (_allocator) Section<ELFT>(
-          _targetInfo, sectionName, contentType, permissions, section_order);
+      section =
+          getSection(sectionName, contentType, permissions, section_order);
       section->setOrder(section_order);
       _sections.push_back(section);
       _sectionMap.insert(std::make_pair(sectionKey, section));
@@ -456,13 +471,13 @@ DefaultLayout<ELFT>::mergeSimiliarSections() {
   }
 }
 
-template<class ELFT>
-void 
-DefaultLayout<ELFT>::assignSectionsToSegments() {
+template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
+  // TODO: Do we want to give a chance for the targetHandlers
+  // to sort segments in an arbitrary order ? 
   // sort the sections by their order as defined by the layout
   std::stable_sort(_sections.begin(), _sections.end(),
-  [](Chunk<ELFT> *A, Chunk<ELFT> *B) {
-     return A->order() < B->order();
+                   [](Chunk<ELFT> *A, Chunk<ELFT> *B) {
+    return A->order() < B->order();
   });
   // Merge all sections
   mergeSimiliarSections();
@@ -482,11 +497,11 @@ DefaultLayout<ELFT>::assignSectionsToSegments() {
           continue;
         msi->setHasSegment();
         section->setSegment(getSegmentType(section));
-        const StringRef segmentName = section->segmentKindToStr();
+        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<ELFT> *>
-          currentSegment(key, nullptr);
+        const std::pair<SegmentKey, Segment<ELFT> *> currentSegment(key,
+                                                                    nullptr);
         std::pair<typename SegmentMapT::iterator, bool>
                             segmentInsert(_segmentMap.insert(currentSegment));
         Segment<ELFT> *segment;
@@ -504,11 +519,10 @@ DefaultLayout<ELFT>::assignSectionsToSegments() {
   }
 }
 
-template<class ELFT>
-void
-DefaultLayout<ELFT>::assignFileOffsets() {
-  std::sort(_segments.begin(), _segments.end(),
-            Segment<ELFT>::compareSegments);
+template <class ELFT> void DefaultLayout<ELFT>::assignFileOffsets() {
+  // TODO: Do we want to give a chance for the targetHandlers
+  // to sort segments in an arbitrary order ? 
+  std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::compareSegments);
   int ordinal = 0;
   // Compute the number of segments that might be needed, so that the
   // size of the program header can be computed
index 525d360..163f78a 100644 (file)
@@ -32,8 +32,8 @@ public:
   CRuntimeFile(const ELFTargetInfo &ti) : ELFFile<ELFT>(ti, "C runtime") {}
 
   /// \brief add a global absolute atom
-  void addAbsoluteAtom(const StringRef symbolName) {
-    Elf_Sym *symbol = new(_allocator.Allocate<Elf_Sym>()) Elf_Sym;
+  void addAbsoluteAtom(StringRef symbolName) {
+    Elf_Sym *symbol = new (_allocator.Allocate<Elf_Sym>()) Elf_Sym;
     symbol->st_name = 0;
     symbol->st_value = 0;
     symbol->st_shndx = llvm::ELF::SHN_ABS;
@@ -47,7 +47,7 @@ public:
   }
 
   /// \brief add an undefined atom 
-  void addUndefinedAtom(const StringRef symbolName) {
+  void addUndefinedAtom(StringRef symbolName) {
     Elf_Sym *symbol = new (_allocator) Elf_Sym;
     symbol->st_name = 0;
     symbol->st_value = 0;
index 7413cc4..f4642aa 100644 (file)
@@ -48,7 +48,7 @@ template <class ELFT> class ELFFile : public File {
   typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
 
 public:
-  ELFFile(const ELFTargetInfo &ti, const StringRef name)
+  ELFFile(const ELFTargetInfo &ti, StringRef name)
       : File(name), _elfTargetInfo(ti) {
   }
 
index cc0d090..f6c46c6 100644 (file)
@@ -45,7 +45,7 @@ public:
   };
   // Create a section object, the section is set to the default type if the
   // caller doesnot set it
-  Section(const ELFTargetInfo &, const StringRef sectionName,
+  Section(const ELFTargetInfo &, StringRef sectionName,
           const int32_t contentType, const int32_t contentPermissions,
           const int32_t order, const SectionKind kind = K_Default);
 
@@ -54,6 +54,18 @@ public:
     return _sectionKind;
   }
 
+  /// set the section Kind, this function is needed by the targetHandler
+  /// to set the target section
+  inline void setKind(SectionKind k) { _sectionKind = k; }
+
+  /// Is the section part of any segment, Target sections must override 
+  /// this function
+  virtual bool hasOutputSegment() {
+    assert((_sectionKind != K_Target) && 
+           "Cannot determine if the targetSection has any output segment");
+    return false;
+  }
+
   /// Align the offset to the required modulus defined by the atom alignment
   uint64_t alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign);
 
@@ -83,7 +95,7 @@ public:
   /// \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
-  inline bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
+  inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
     for (auto ai : _atoms) {
       if (ai->_atom->name() == name) {
         addr = ai->_virtualAddr;
@@ -178,7 +190,7 @@ protected:
 // Create a section object, the section is set to the default type if the
 // caller doesnot set it
 template <class ELFT>
-Section<ELFT>::Section(const ELFTargetInfo &ti, const StringRef sectionName,
+Section<ELFT>::Section(const ELFTargetInfo &ti, StringRef sectionName,
                        const int32_t contentType,
                        const int32_t contentPermissions, const int32_t order,
                        const SectionKind kind)
@@ -513,7 +525,7 @@ public:
     return c->kind() == Section<ELFT>::K_StringTable;
   }
 
-  uint64_t addString(const StringRef symname);
+  uint64_t addString(StringRef symname);
 
   void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
 
@@ -536,9 +548,7 @@ StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str,
   this->setOrder(order);
 }
 
-template<class ELFT>
-uint64_t
-StringTable<ELFT>::addString(const StringRef symname) {
+template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) {
   _strings.push_back(symname);
   uint64_t offset = this->_fsize;
   this->_fsize += symname.size() + 1;
index 77a023a..12ced70 100644 (file)
@@ -108,7 +108,7 @@ public:
   typedef typename std::vector<SegmentSlice<ELFT> *>::iterator SliceIter;
   typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
 
-  Segment(const ELFTargetInfo &ti, const StringRef name,
+  Segment(const ELFTargetInfo &ti, StringRef name,
           const Layout::SegmentType type);
 
   /// append a section to a segment
@@ -195,7 +195,7 @@ protected:
 };
 
 template <class ELFT>
-Segment<ELFT>::Segment(const ELFTargetInfo &ti, const StringRef name,
+Segment<ELFT>::Segment(const ELFTargetInfo &ti, StringRef name,
                        const Layout::SegmentType type)
     : Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment, ti), _segmentType(type),
       _flags(0), _atomflags(0) {
index 9e4a63b..b2a5cdd 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <memory>
 #include <vector>
-#include <unordered_map>
 
 namespace lld {
 namespace elf {
@@ -75,30 +74,6 @@ template <class ELFT> class TargetHandler : public TargetHandlerBase {
 public:
   TargetHandler(ELFTargetInfo &targetInfo) : _targetInfo(targetInfo) {}
 
-  /// Register a Target, so that the target backend may choose on how to merge
-  /// individual atoms within the section, this is a way to control output order
-  /// of atoms that is determined by the target
-  void registerTargetSection(StringRef name,
-                             DefinedAtom::ContentPermissions perm) {
-    const TargetSectionKey targetSection(name, perm);
-    if (_registeredTargetSections.find(targetSection) ==
-        _registeredTargetSections.end())
-      _registeredTargetSections.insert(std::make_pair(targetSection, true));
-  }
-
-  /// Check if the section is registered given the section name and its
-  /// contentType, if they are registered the target would need to 
-  /// create a section so that atoms insert, atom virtual address assignment
-  /// could be overridden and controlled by the Target
-  bool isSectionRegisteredByTarget(StringRef name,
-                                   DefinedAtom::ContentPermissions perm) {
-    const TargetSectionKey targetSection(name, perm);
-    if (_registeredTargetSections.find(targetSection) ==
-        _registeredTargetSections.end())
-      return false;
-    return true;
-  }
-
   /// If the target overrides ELF header information, this API would
   /// return true, so that the target can set all fields specific to
   /// that target
@@ -131,37 +106,8 @@ public:
   /// symbols over to small data, this would also be used 
   virtual void allocateCommons() = 0;
 
-private:
-  struct TargetSectionKey {
-    TargetSectionKey(StringRef name, DefinedAtom::ContentPermissions perm)
-        : _name(name), _perm(perm) {
-    }
-
-    // Data members
-    const StringRef _name;
-    DefinedAtom::ContentPermissions _perm;
-  };
-
-  struct TargetSectionKeyHash {
-    int64_t operator()(const TargetSectionKey &k) const {
-      return llvm::hash_combine(k._name, k._perm);
-    }
-  };
-
-  struct TargetSectionKeyEq {
-    bool operator()(const TargetSectionKey &lhs,
-                    const TargetSectionKey &rhs) const {
-      return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm));
-    }
-  };
-
-  typedef std::unordered_map<TargetSectionKey, bool, TargetSectionKeyHash,
-                             TargetSectionKeyEq> RegisteredTargetSectionMapT;
-  typedef typename RegisteredTargetSectionMapT::iterator RegisteredTargetSectionMapIterT;
-
 protected:
   const ELFTargetInfo &_targetInfo;
-  RegisteredTargetSectionMapT _registeredTargetSections;
 };
 } // end namespace elf
 } // end namespace lld
index e4f17b8..20cc7d0 100644 (file)
@@ -21,42 +21,8 @@ namespace elf {
 /// be changed in the final layout
 template <class ELFT> class TargetLayout : public DefaultLayout<ELFT> {
 public:
-  TargetLayout(ELFTargetInfo &targetInfo)
-      : DefaultELFLayout<ELFT>(targetInfo) {
-  }
-
-  /// isTargetSection provides a way to determine if the section that
-  /// we are processing has been registered by the target and the target
-  /// wants to handle them. 
-  /// For example: the Writer may be processing a section but the target
-  /// might want to override the functionality on how atoms are inserted
-  /// into the section. Such sections are set the K_TargetSection flag in
-  /// the SectionKind after they are created
-  virtual bool isTargetSection(const StringRef name, const int32_t contentType,
-                               const int32_t contentPermissions) = 0;
-
-  /// The target may want to override the sectionName to a different
-  /// section Name in the output
-  virtual StringRef sectionName(const StringRef name, const int32_t contentType,
-                                const int32_t contentPermissions) = 0;
-
-  /// The target may want to override the section order that has been 
-  /// set by the DefaultLayout
-  virtual Layout::SectionOrder getSectionOrder(
-      const StringRef name, int32_t contentType,
-      int32_t contentPermissions) = 0;
-
-  /// The target can set the segment type for a Section
-  virtual Layout::SegmentType segmentType(Section<ELFT> *section) const = 0;
-
-  /// Returns true/false depending on whether the section has a Output
-  //  segment or not
-  bool hasOutputSegment(Section<ELFT> *section) = 0;
-
-  /// Returns the target Section for a section name and content Type
-  Section<ELFT> *getSection(const StringRef name,
-                            DefinedAtom::ContentPermissions permissions) = 0;
-
+  TargetLayout(const ELFTargetInfo &targetInfo) 
+    : DefaultLayout<ELFT>(targetInfo) {}
 };
 } // end namespace elf
 } // end namespace lld
index 6e3bc43..15f167d 100644 (file)
@@ -10,6 +10,7 @@
 #include "lld/ReaderWriter/Writer.h"
 
 #include "DefaultLayout.h"
+#include "TargetLayout.h"
 #include "ExecutableAtoms.h"
 
 #include "lld/ReaderWriter/ELFTargetInfo.h"
@@ -54,8 +55,9 @@ private:
   void createDefaultSections();
 
   const ELFTargetInfo &_targetInfo;
+  TargetHandler<ELFT> &_targetHandler;
 
-  typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
+  typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
   std::unique_ptr<KindHandler> _referenceKindHandler;
   AtomToAddress _atomToAddressMap;
   llvm::BumpPtrAllocator _chunkAllocate;
@@ -72,17 +74,17 @@ private:
 //===----------------------------------------------------------------------===//
 //  ExecutableWriter
 //===----------------------------------------------------------------------===//
-template<class ELFT>
+template <class ELFT>
 ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
-  : _targetInfo(ti)
-  , _referenceKindHandler(KindHandler::makeHandler(
-                              ti.getTriple().getArch(), ti.isLittleEndian()))
-  , _runtimeFile(ti) {
-  _layout = new DefaultLayout<ELFT>(ti);
+    : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
+      _referenceKindHandler(KindHandler::makeHandler(ti.getTriple().getArch(),
+                                                     ti.isLittleEndian())),
+      _runtimeFile(ti) {
+  _layout = new TargetLayout<ELFT>(_targetInfo);
 }
 
-template<class ELFT>
-void ExecutableWriter<ELFT>::buildChunks(const File &file){
+template <class ELFT>
+void ExecutableWriter<ELFT>::buildChunks(const File &file) {
   for (const DefinedAtom *definedAtom : file.defined() ) {
     _layout->addAtom(definedAtom);
   }
@@ -163,10 +165,12 @@ void ExecutableWriter<ELFT>::addDefaultAtoms() {
 }
 
 /// \brief Hook in lld to add CRuntime file 
-template<class ELFT>
+template <class ELFT>
 void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
   addDefaultAtoms();
   inputFiles.prependFile(_runtimeFile);
+  // Give a chance for the target to add atoms
+  _targetHandler.addFiles(inputFiles);
 }
 
 /// Finalize the value of all the absolute symbols that we 
@@ -260,16 +264,21 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
   if (ec)
     return ec;
 
-  _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
-                                                            : ELF::ELFCLASS32);
-  _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
-                                    ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
-  _Header->e_ident(ELF::EI_VERSION, 1);
-  _Header->e_ident(ELF::EI_OSABI, 0);
+  _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
+                       ELF::ELFCLASS32);
+  _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
+                       ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
   _Header->e_type(_targetInfo.getOutputType());
   _Header->e_machine(_targetInfo.getOutputMachine());
-  _Header->e_version(1);
-  _Header->e_entry(0ULL);
+
+  if (!_targetHandler.doesOverrideHeader()) {
+    _Header->e_ident(ELF::EI_VERSION, 1);
+    _Header->e_ident(ELF::EI_OSABI, 0);
+    _Header->e_version(1);
+  } else {
+    // override the contents of the ELF Header
+    _targetHandler.setHeaderInfo(_Header);
+  }
   _Header->e_phoff(_programHeader->fileOffset());
   _Header->e_shoff(_shdrtab->fileOffset());
   _Header->e_phentsize(_programHeader->entsize());
@@ -314,6 +323,9 @@ void ExecutableWriter<ELFT>::createDefaultSections() {
   _shdrtab->setStringSection(_shstrtab);
   _symtab->setStringSection(_strtab);
   _layout->addSection(_shdrtab);
+
+  // give a chance for the target to add sections
+  _targetHandler.createDefaultSections();
 }
 } // namespace elf