diff options
author | Shankar Easwaran <shankare@codeaurora.org> | 2013-01-30 07:11:43 +0000 |
---|---|---|
committer | Shankar Easwaran <shankare@codeaurora.org> | 2013-01-30 07:11:43 +0000 |
commit | a6f00fe0837778c45dfacb859386ee7e797d4f78 (patch) | |
tree | b7076d8b9bdfb9ad2c98d2c121300d78e3b910f8 | |
parent | 41778c3fa9bfa446cf3782968161d88ff3a2c939 (diff) | |
download | bcm5719-llvm-a6f00fe0837778c45dfacb859386ee7e797d4f78.tar.gz bcm5719-llvm-a6f00fe0837778c45dfacb859386ee7e797d4f78.zip |
add targethandler hooks from Writer and cleanup
llvm-svn: 173904
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Chunk.h | 8 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultLayout.h | 112 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ExecutableAtoms.h | 6 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/File.h | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 24 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SegmentChunks.h | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/TargetHandler.h | 54 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/TargetLayout.h | 38 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Writer.cpp | 48 |
9 files changed, 121 insertions, 175 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Chunk.h b/lld/lib/ReaderWriter/ELF/Chunk.h index 801896ecce2..f815c84f5ea 100644 --- a/lld/lib/ReaderWriter/ELF/Chunk.h +++ b/lld/lib/ReaderWriter/ELF/Chunk.h @@ -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; diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index c6dcfde27e3..035600a65ae 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -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 diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h index 525d3607a39..163f78aeb25 100644 --- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h +++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h @@ -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; diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h index 7413cc4681e..f4642aa294e 100644 --- a/lld/lib/ReaderWriter/ELF/File.h +++ b/lld/lib/ReaderWriter/ELF/File.h @@ -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) { } diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index cc0d0909ec1..f6c46c64924 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -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; diff --git a/lld/lib/ReaderWriter/ELF/SegmentChunks.h b/lld/lib/ReaderWriter/ELF/SegmentChunks.h index 77a023a6b28..12ced7036ac 100644 --- a/lld/lib/ReaderWriter/ELF/SegmentChunks.h +++ b/lld/lib/ReaderWriter/ELF/SegmentChunks.h @@ -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) { diff --git a/lld/lib/ReaderWriter/ELF/TargetHandler.h b/lld/lib/ReaderWriter/ELF/TargetHandler.h index 9e4a63ba1bb..b2a5cddcf04 100644 --- a/lld/lib/ReaderWriter/ELF/TargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/TargetHandler.h @@ -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 diff --git a/lld/lib/ReaderWriter/ELF/TargetLayout.h b/lld/lib/ReaderWriter/ELF/TargetLayout.h index e4f17b8b5fd..20cc7d03804 100644 --- a/lld/lib/ReaderWriter/ELF/TargetLayout.h +++ b/lld/lib/ReaderWriter/ELF/TargetLayout.h @@ -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 diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp index 6e3bc438e49..15f167d79af 100644 --- a/lld/lib/ReaderWriter/ELF/Writer.cpp +++ b/lld/lib/ReaderWriter/ELF/Writer.cpp @@ -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 |