Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -48,6 +48,29 @@ public: typedef typename ELFT::uint uintX_t; typedef typename ELFT::Shdr Elf_Shdr; + enum Kind { + Base, + BuildId, + Dynamic, + EHFrame, + EHFrameHdr, + GnuHashTable, + Got, + GotPlt, + HashTable, + Interp, + Merge, + MipsReginfo, + MipsOptions, + Plt, + Regular, + Reloc, + StrTable, + SymTable, + VersDef, + VersNeed, + VersTable + }; OutputSectionBase(StringRef Name, uint32_t Type, uintX_t Flags); void setVA(uintX_t VA) { Header.sh_addr = VA; } @@ -58,6 +81,10 @@ StringRef getName() { return Name; } virtual void addSection(InputSectionBase *C) {} + virtual Kind getKind() const { return Base; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == Base; + } unsigned SectionIndex; @@ -108,6 +135,8 @@ uintX_t getGlobalDynAddr(const SymbolBody &B) const; uintX_t getGlobalDynOffset(const SymbolBody &B) const; uintX_t getNumEntries() const { return Entries.size(); } + typename Base::Kind getKind() const override { return Base::Got; } + static bool classof(const Base *B) { return B->getKind() == Base::Got; } // Returns the symbol which corresponds to the first entry of the global part // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic @@ -158,6 +187,7 @@ template class GotPltSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; + typedef OutputSectionBase Base; public: GotPltSection(); @@ -165,6 +195,8 @@ void writeTo(uint8_t *Buf) override; void addEntry(SymbolBody &Sym); bool empty() const; + typename Base::Kind getKind() const override { return Base::GotPlt; } + static bool classof(const Base *B) { return B->getKind() == Base::GotPlt; } private: std::vector Entries; @@ -180,6 +212,8 @@ void writeTo(uint8_t *Buf) override; void addEntry(SymbolBody &Sym); bool empty() const { return Entries.empty(); } + typename Base::Kind getKind() const override { return Base::Plt; } + static bool classof(const Base *B) { return B->getKind() == Base::Plt; } private: std::vector> Entries; @@ -219,6 +253,8 @@ template class SymbolTableSection final : public OutputSectionBase { + typedef OutputSectionBase Base; + public: typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Sym Elf_Sym; @@ -231,6 +267,8 @@ void addSymbol(SymbolBody *Body); StringTableSection &getStrTabSec() const { return StrTabSec; } unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } + typename Base::Kind getKind() const override { return Base::SymTable; } + static bool classof(const Base *B) { return B->getKind() == Base::SymTable; } ArrayRef> getSymbols() const { return Symbols; @@ -261,11 +299,14 @@ class VersionDefinitionSection final : public OutputSectionBase { typedef typename ELFT::Verdef Elf_Verdef; typedef typename ELFT::Verdaux Elf_Verdaux; + typedef OutputSectionBase Base; public: VersionDefinitionSection(); void finalize() override; void writeTo(uint8_t *Buf) override; + typename Base::Kind getKind() const override { return Base::VersDef; } + static bool classof(const Base *B) { return B->getKind() == Base::VersDef; } private: void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff); @@ -281,12 +322,15 @@ // the own object or in any of the dependencies. template class VersionTableSection final : public OutputSectionBase { + typedef OutputSectionBase Base; typedef typename ELFT::Versym Elf_Versym; public: VersionTableSection(); void finalize() override; void writeTo(uint8_t *Buf) override; + typename Base::Kind getKind() const override { return Base::VersTable; } + static bool classof(const Base *B) { return B->getKind() == Base::VersTable; } }; // The .gnu.version_r section defines the version identifiers used by @@ -296,6 +340,7 @@ // mapping from version identifiers to version names. template class VersionNeedSection final : public OutputSectionBase { + typedef OutputSectionBase Base; typedef typename ELFT::Verneed Elf_Verneed; typedef typename ELFT::Vernaux Elf_Vernaux; @@ -312,6 +357,8 @@ void finalize() override; void writeTo(uint8_t *Buf) override; size_t getNeedNum() const { return Needed.size(); } + typename Base::Kind getKind() const override { return Base::VersNeed; } + static bool classof(const Base *B) { return B->getKind() == Base::VersNeed; } }; template @@ -319,6 +366,7 @@ typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; typedef typename ELFT::uint uintX_t; + typedef OutputSectionBase Base; public: RelocationSection(StringRef Name, bool Sort); @@ -327,6 +375,8 @@ void finalize() override; void writeTo(uint8_t *Buf) override; bool hasRelocs() const { return !Relocs.empty(); } + typename Base::Kind getKind() const override { return Base::Reloc; } + static bool classof(const Base *B) { return B->getKind() == Base::Reloc; } private: bool Sort; @@ -335,6 +385,8 @@ template class OutputSection final : public OutputSectionBase { + typedef OutputSectionBase Base; + public: typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Sym Elf_Sym; @@ -348,12 +400,15 @@ void writeTo(uint8_t *Buf) override; void finalize() override; void assignOffsets() override; + typename Base::Kind getKind() const override { return Base::Regular; } + static bool classof(const Base *B) { return B->getKind() == Base::Regular; } std::vector *> Sections; }; template class MergeOutputSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; + typedef OutputSectionBase Base; public: MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags, @@ -364,6 +419,8 @@ void finalize() override; void finalizePieces() override; bool shouldTailMerge() const; + typename Base::Kind getKind() const override { return Base::Merge; } + static bool classof(const Base *B) { return B->getKind() == Base::Merge; } private: llvm::StringTableBuilder Builder; @@ -382,6 +439,7 @@ typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; + typedef OutputSectionBase Base; public: EhOutputSection(); @@ -390,6 +448,8 @@ bool empty() const { return Sections.empty(); } void addSection(InputSectionBase *S) override; + typename Base::Kind getKind() const override { return Base::EHFrame; } + static bool classof(const Base *B) { return B->getKind() == Base::EHFrame; } size_t NumFdes = 0; @@ -416,13 +476,19 @@ template class InterpSection final : public OutputSectionBase { + typedef OutputSectionBase Base; + public: InterpSection(); void writeTo(uint8_t *Buf) override; + typename Base::Kind getKind() const override { return Base::Interp; } + static bool classof(const Base *B) { return B->getKind() == Base::Interp; } }; template class StringTableSection final : public OutputSectionBase { + typedef OutputSectionBase Base; + public: typedef typename ELFT::uint uintX_t; StringTableSection(StringRef Name, bool Dynamic); @@ -431,6 +497,8 @@ unsigned getSize() const { return Size; } void finalize() override { this->Header.sh_size = getSize(); } bool isDynamic() const { return Dynamic; } + typename Base::Kind getKind() const override { return Base::StrTable; } + static bool classof(const Base *B) { return B->getKind() == Base::StrTable; } private: const bool Dynamic; @@ -442,11 +510,14 @@ template class HashTableSection final : public OutputSectionBase { typedef typename ELFT::Word Elf_Word; + typedef OutputSectionBase Base; public: HashTableSection(); void finalize() override; void writeTo(uint8_t *Buf) override; + typename Base::Kind getKind() const override { return Base::HashTable; } + static bool classof(const Base *B) { return B->getKind() == Base::HashTable; } }; // Outputs GNU Hash section. For detailed explanation see: @@ -456,6 +527,7 @@ typedef typename ELFT::Off Elf_Off; typedef typename ELFT::Word Elf_Word; typedef typename ELFT::uint uintX_t; + typedef OutputSectionBase Base; public: GnuHashTableSection(); @@ -465,6 +537,10 @@ // Adds symbols to the hash table. // Sorts the input to satisfy GNU hash section requirements. void addSymbols(std::vector> &Symbols); + typename Base::Kind getKind() const override { return Base::GnuHashTable; } + static bool classof(const Base *B) { + return B->getKind() == Base::GnuHashTable; + } private: static unsigned calcNBuckets(unsigned NumHashed); @@ -525,16 +601,23 @@ explicit DynamicSection(); void finalize() override; void writeTo(uint8_t *Buf) override; + typename Base::Kind getKind() const override { return Base::Dynamic; } + static bool classof(const Base *B) { return B->getKind() == Base::Dynamic; } }; template class MipsReginfoOutputSection final : public OutputSectionBase { typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; + typedef OutputSectionBase Base; public: MipsReginfoOutputSection(); void writeTo(uint8_t *Buf) override; void addSection(InputSectionBase *S) override; + typename Base::Kind getKind() const override { return Base::MipsReginfo; } + static bool classof(const Base *B) { + return B->getKind() == Base::MipsReginfo; + } private: uint32_t GprMask = 0; @@ -544,11 +627,16 @@ class MipsOptionsOutputSection final : public OutputSectionBase { typedef llvm::object::Elf_Mips_Options Elf_Mips_Options; typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; + typedef OutputSectionBase Base; public: MipsOptionsOutputSection(); void writeTo(uint8_t *Buf) override; void addSection(InputSectionBase *S) override; + typename Base::Kind getKind() const override { return Base::MipsOptions; } + static bool classof(const Base *B) { + return B->getKind() == Base::MipsOptions; + } private: uint32_t GprMask = 0; @@ -566,12 +654,17 @@ template class EhFrameHeader final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; + typedef OutputSectionBase Base; public: EhFrameHeader(); void finalize() override; void writeTo(uint8_t *Buf) override; void addFde(uint32_t Pc, uint32_t FdeVA); + typename Base::Kind getKind() const override { return Base::EHFrameHdr; } + static bool classof(const Base *B) { + return B->getKind() == Base::EHFrameHdr; + } private: struct FdeData { @@ -583,9 +676,13 @@ }; template class BuildIdSection : public OutputSectionBase { + typedef OutputSectionBase Base; + public: void writeTo(uint8_t *Buf) override; virtual void writeBuildId(ArrayRef> Bufs) = 0; + typename Base::Kind getKind() const override { return Base::BuildId; } + static bool classof(const Base *B) { return B->getKind() == Base::BuildId; } protected: BuildIdSection(size_t HashSize);