Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -29,7 +29,7 @@ template class DefinedRegular; template class ObjectFile; template class OutputSection; -template class OutputSectionBase; +class OutputSectionBase; // We need non-template input section class to store symbol layout // in linker script parser structures, where we do not have ELFT @@ -104,7 +104,7 @@ uintX_t Entsize, uint32_t Link, uint32_t Info, uintX_t Addralign, ArrayRef Data, StringRef Name, Kind SectionKind); - OutputSectionBase *OutSec = nullptr; + OutputSectionBase *OutSec = nullptr; // This pointer points to the "real" instance of this instance. // Usually Repl == this. However, if ICF merges two sections, Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -32,7 +32,7 @@ class SymbolBody; template class InputSectionBase; template class InputSection; -template class OutputSectionBase; +class OutputSectionBase; template class OutputSectionFactory; class InputSectionData; @@ -240,7 +240,7 @@ bool isDefined(StringRef S) override; bool isAbsolute(StringRef S) override; - std::vector *> *OutputSections; + std::vector *OutputSections; int getSectionIndex(StringRef Name); @@ -262,13 +262,13 @@ uintX_t Dot; uintX_t LMAOffset = 0; - OutputSectionBase *CurOutSec = nullptr; + OutputSectionBase *CurOutSec = nullptr; uintX_t ThreadBssOffset = 0; - void switchTo(OutputSectionBase *Sec); + void switchTo(OutputSectionBase *Sec); void flush(); void output(InputSection *Sec); void process(BaseCommand &Base); - llvm::DenseSet *> AlreadyOutputOS; + llvm::DenseSet AlreadyOutputOS; llvm::DenseSet AlreadyOutputIS; }; Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -229,7 +229,7 @@ // section for now. for (InputSectionData *S : I->Sections) { auto *S2 = static_cast *>(S); - S2->OutSec = (OutputSectionBase *)-1; + S2->OutSec = (OutputSectionBase *)-1; } } @@ -298,7 +298,7 @@ void LinkerScript::addSection(OutputSectionFactory &Factory, InputSectionBase *Sec, StringRef Name) { - OutputSectionBase *OutSec; + OutputSectionBase *OutSec; bool IsNew; std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); if (IsNew) @@ -373,8 +373,7 @@ // is an offset from beginning of section and regular // symbols whose value is absolute. template -static void assignSectionSymbol(SymbolAssignment *Cmd, - OutputSectionBase *Sec, +static void assignSectionSymbol(SymbolAssignment *Cmd, OutputSectionBase *Sec, typename ELFT::uint Value) { if (!Cmd->Sym) return; @@ -388,14 +387,14 @@ Body->Value = Cmd->Expression(Value); } -template static bool isTbss(OutputSectionBase *Sec) { +template static bool isTbss(OutputSectionBase *Sec) { return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS; } template void LinkerScript::output(InputSection *S) { if (!AlreadyOutputIS.insert(S).second) return; - bool IsTbss = isTbss(CurOutSec); + bool IsTbss = isTbss(CurOutSec); uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; Pos = alignTo(Pos, S->Alignment); @@ -425,7 +424,7 @@ } template -void LinkerScript::switchTo(OutputSectionBase *Sec) { +void LinkerScript::switchTo(OutputSectionBase *Sec) { if (CurOutSec == Sec) return; if (AlreadyOutputOS.count(Sec)) @@ -435,7 +434,7 @@ CurOutSec = Sec; Dot = alignTo(Dot, CurOutSec->Addralign); - CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot; + CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot; // If neither AT nor AT> is specified for an allocatable section, the linker // will set the LMA such that the difference between VMA and LMA for the @@ -480,11 +479,10 @@ } template -static std::vector *> -findSections(StringRef Name, - const std::vector *> &Sections) { - std::vector *> Ret; - for (OutputSectionBase *Sec : Sections) +static std::vector +findSections(StringRef Name, const std::vector &Sections) { + std::vector Ret; + for (OutputSectionBase *Sec : Sections) if (Sec->getName() == Name) Ret.push_back(Sec); return Ret; @@ -494,8 +492,8 @@ void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) { if (Cmd->LMAExpr) LMAOffset = Cmd->LMAExpr(Dot) - Dot; - std::vector *> Sections = - findSections(Cmd->Name, *OutputSections); + std::vector Sections = + findSections(Cmd->Name, *OutputSections); if (Sections.empty()) return; switchTo(Sections[0]); @@ -508,7 +506,7 @@ .base(); for (auto I = Cmd->Commands.begin(); I != E; ++I) process(**I); - for (OutputSectionBase *Base : Sections) + for (OutputSectionBase *Base : Sections) switchTo(Base); flush(); std::for_each(E, Cmd->Commands.end(), @@ -528,8 +526,8 @@ auto *Cmd = dyn_cast(Base.get()); if (!Cmd) return false; - std::vector *> Secs = - findSections(Cmd->Name, *OutputSections); + std::vector Secs = + findSections(Cmd->Name, *OutputSections); if (!Secs.empty()) return false; for (const std::unique_ptr &I : Cmd->Commands) @@ -549,8 +547,8 @@ auto *Cmd = dyn_cast(Base.get()); if (!Cmd) continue; - std::vector *> Secs = - findSections(Cmd->Name, *OutputSections); + std::vector Secs = + findSections(Cmd->Name, *OutputSections); if (!Secs.empty()) { Flags = Secs[0]->Flags; Type = Secs[0]->Type; @@ -597,7 +595,7 @@ // This loops creates or moves commands as needed so that they are in the // correct order. int CmdIndex = 0; - for (OutputSectionBase *Sec : *OutputSections) { + for (OutputSectionBase *Sec : *OutputSections) { StringRef Name = Sec->getName(); // Find the last spot where we can insert a command and still get the @@ -633,8 +631,8 @@ if (Cmd->Name == ".") { Dot = Cmd->Expression(Dot); } else if (Cmd->Sym) { - assignSectionSymbol(Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], - Dot); + assignSectionSymbol( + Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], Dot); } continue; } @@ -653,9 +651,9 @@ } uintX_t MinVA = std::numeric_limits::max(); - for (OutputSectionBase *Sec : *OutputSections) { + for (OutputSectionBase *Sec : *OutputSections) { if (Sec->Flags & SHF_ALLOC) - MinVA = std::min(MinVA, Sec->Addr); + MinVA = std::min(MinVA, Sec->Addr); else Sec->Addr = 0; } @@ -730,7 +728,7 @@ } // Add output sections to program headers. - for (OutputSectionBase *Sec : *OutputSections) { + for (OutputSectionBase *Sec : *OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -831,7 +829,7 @@ template uint64_t LinkerScript::getOutputSectionAddress(StringRef Name) { - for (OutputSectionBase *Sec : *OutputSections) + for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec->Addr; error("undefined section " + Name); @@ -840,7 +838,7 @@ template uint64_t LinkerScript::getOutputSectionLMA(StringRef Name) { - for (OutputSectionBase *Sec : *OutputSections) + for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec->getLMA(); error("undefined section " + Name); @@ -849,7 +847,7 @@ template uint64_t LinkerScript::getOutputSectionSize(StringRef Name) { - for (OutputSectionBase *Sec : *OutputSections) + for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec->Size; error("undefined section " + Name); @@ -858,7 +856,7 @@ template uint64_t LinkerScript::getOutputSectionAlign(StringRef Name) { - for (OutputSectionBase *Sec : *OutputSections) + for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec->Addralign; error("undefined section " + Name); Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -43,10 +43,8 @@ // input sections, others are created by the linker. // The writer creates multiple OutputSections and assign them unique, // non-overlapping file offsets and VAs. -template class OutputSectionBase { +class OutputSectionBase { public: - typedef typename ELFT::uint uintX_t; - typedef typename ELFT::Shdr Elf_Shdr; enum Kind { Base, Dynamic, @@ -70,15 +68,15 @@ VersTable }; - OutputSectionBase(StringRef Name, uint32_t Type, uintX_t Flags); - void setLMAOffset(uintX_t LMAOff) { LMAOffset = LMAOff; } - uintX_t getLMA() const { return Addr + LMAOffset; } - void writeHeaderTo(Elf_Shdr *SHdr); + OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags); + void setLMAOffset(uint64_t LMAOff) { LMAOffset = LMAOff; } + uint64_t getLMA() const { return Addr + LMAOffset; } + template void writeHeaderTo(typename ELFT::Shdr *SHdr); StringRef getName() const { return Name; } - virtual void addSection(InputSectionBase *C) {} + virtual void addSection(InputSectionData *C) {} virtual Kind getKind() const { return Base; } - static bool classof(const OutputSectionBase *B) { + static bool classof(const OutputSectionBase *B) { return B->getKind() == Base; } @@ -86,7 +84,7 @@ uint32_t getPhdrFlags() const; - void updateAlignment(uintX_t Alignment) { + void updateAlignment(uint64_t Alignment) { if (Alignment > Addralign) Addralign = Alignment; } @@ -101,7 +99,7 @@ // between their file offsets should be equal to difference between their // virtual addresses. To compute some section offset we use the following // formula: Off = Off_first + VA - VA_first. - OutputSectionBase *FirstInPtLoad = nullptr; + OutputSectionBase *FirstInPtLoad = nullptr; virtual void finalize() {} virtual void finalizePieces() {} @@ -112,21 +110,20 @@ StringRef Name; // The following fields correspond to Elf_Shdr members. - uintX_t Size = 0; - uintX_t Entsize = 0; - uintX_t Addralign = 0; - uintX_t Offset = 0; - uintX_t Flags = 0; - uintX_t LMAOffset = 0; - uintX_t Addr = 0; + uint64_t Size = 0; + uint64_t Entsize = 0; + uint64_t Addralign = 0; + uint64_t Offset = 0; + uint64_t Flags = 0; + uint64_t LMAOffset = 0; + uint64_t Addr = 0; uint32_t ShName = 0; uint32_t Type = 0; uint32_t Info = 0; uint32_t Link = 0; }; -template -class GdbIndexSection final : public OutputSectionBase { +template class GdbIndexSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; const unsigned OffsetTypeSize = 4; @@ -150,8 +147,7 @@ uint32_t CuTypesOffset; }; -template class GotSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +template class GotSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; public: @@ -167,8 +163,10 @@ uintX_t getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const; uintX_t getGlobalDynAddr(const SymbolBody &B) const; uintX_t getGlobalDynOffset(const SymbolBody &B) const; - typename Base::Kind getKind() const override { return Base::Got; } - static bool classof(const Base *B) { return B->getKind() == Base::Got; } + Kind getKind() const override { return Got; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == 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 @@ -196,7 +194,7 @@ uint32_t TlsIndexOff = -1; uint32_t MipsPageEntries = 0; // Output sections referenced by MIPS GOT relocations. - llvm::SmallPtrSet *, 10> MipsOutSections; + llvm::SmallPtrSet MipsOutSections; llvm::DenseMap MipsLocalGotPos; // MIPS ABI requires to create unique GOT entry for each Symbol/Addend @@ -217,10 +215,8 @@ void writeMipsGot(uint8_t *Buf); }; -template -class GotPltSection final : public OutputSectionBase { +template class GotPltSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; - typedef OutputSectionBase Base; public: GotPltSection(); @@ -228,15 +224,16 @@ 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; } + Kind getKind() const override { return GotPlt; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == GotPlt; + } private: std::vector Entries; }; -template class PltSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +template class PltSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; public: @@ -245,8 +242,10 @@ 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; } + Kind getKind() const override { return Plt; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == Plt; + } private: std::vector> Entries; @@ -262,7 +261,7 @@ : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {} - DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec, + DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec, uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, uintX_t Addend) : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec), @@ -271,14 +270,14 @@ uintX_t getOffset() const; uintX_t getAddend() const; uint32_t getSymIndex() const; - const OutputSectionBase *getOutputSec() const { return OutputSec; } + const OutputSectionBase *getOutputSec() const { return OutputSec; } uint32_t Type; private: SymbolBody *Sym; const InputSectionBase *InputSec = nullptr; - const OutputSectionBase *OutputSec = nullptr; + const OutputSectionBase *OutputSec = nullptr; uintX_t OffsetInSec; bool UseSymVA; uintX_t Addend; @@ -290,8 +289,8 @@ }; template -class SymbolTableSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +class SymbolTableSection final : public OutputSectionBase { + typedef OutputSectionBase Base; public: typedef typename ELFT::Shdr Elf_Shdr; @@ -317,7 +316,7 @@ void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); - const OutputSectionBase *getOutputSection(SymbolBody *Sym); + const OutputSectionBase *getOutputSection(SymbolBody *Sym); // A vector of symbols and their string table offsets. std::vector Symbols; @@ -332,17 +331,18 @@ // The section shall contain an array of Elf_Verdef structures, optionally // followed by an array of Elf_Verdaux structures. template -class VersionDefinitionSection final : public OutputSectionBase { +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; } + Kind getKind() const override { return VersDef; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == VersDef; + } private: void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff); @@ -357,16 +357,17 @@ // The values 0 and 1 are reserved. All other values are used for versions in // the own object or in any of the dependencies. template -class VersionTableSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +class VersionTableSection final : public OutputSectionBase { 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; } + Kind getKind() const override { return VersTable; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == VersTable; + } }; // The .gnu.version_r section defines the version identifiers used by @@ -375,8 +376,7 @@ // a reference to a linked list of Elf_Vernaux data structures which define the // mapping from version identifiers to version names. template -class VersionNeedSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +class VersionNeedSection final : public OutputSectionBase { typedef typename ELFT::Verneed Elf_Verneed; typedef typename ELFT::Vernaux Elf_Vernaux; @@ -393,16 +393,16 @@ 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; } + Kind getKind() const override { return VersNeed; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == VersNeed; + } }; -template -class RelocationSection final : public OutputSectionBase { +template class RelocationSection final : public OutputSectionBase { 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); @@ -411,9 +411,11 @@ void finalize() override; void writeTo(uint8_t *Buf) override; bool hasRelocs() const { return !Relocs.empty(); } - typename Base::Kind getKind() const override { return Base::Reloc; } + Kind getKind() const override { return Reloc; } size_t getRelativeRelocCount() const { return NumRelativeRelocs; } - static bool classof(const Base *B) { return B->getKind() == Base::Reloc; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == Reloc; + } private: bool Sort; @@ -421,9 +423,7 @@ std::vector> Relocs; }; -template -class OutputSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +template class OutputSection final : public OutputSectionBase { public: typedef typename ELFT::Shdr Elf_Shdr; @@ -432,33 +432,36 @@ typedef typename ELFT::Rela Elf_Rela; typedef typename ELFT::uint uintX_t; OutputSection(StringRef Name, uint32_t Type, uintX_t Flags); - void addSection(InputSectionBase *C) override; + void addSection(InputSectionData *C) override; void sortInitFini(); void sortCtorsDtors(); 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; } + Kind getKind() const override { return Regular; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == Regular; + } std::vector *> Sections; }; template -class MergeOutputSection final : public OutputSectionBase { +class MergeOutputSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; - typedef OutputSectionBase Base; public: MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags, uintX_t Alignment); - void addSection(InputSectionBase *S) override; + void addSection(InputSectionData *S) override; void writeTo(uint8_t *Buf) override; unsigned getOffset(llvm::CachedHashStringRef Val); 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; } + Kind getKind() const override { return Merge; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == Merge; + } private: llvm::StringTableBuilder Builder; @@ -471,13 +474,11 @@ }; // Output section for .eh_frame. -template -class EhOutputSection final : public OutputSectionBase { +template class EhOutputSection final : public OutputSectionBase { typedef typename ELFT::uint uintX_t; typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; - typedef OutputSectionBase Base; public: EhOutputSection(); @@ -485,9 +486,11 @@ void finalize() override; 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; } + void addSection(InputSectionData *S) override; + Kind getKind() const override { return EHFrame; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == EHFrame; + } size_t NumFdes = 0; @@ -513,8 +516,7 @@ }; template -class StringTableSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +class StringTableSection final : public OutputSectionBase { public: typedef typename ELFT::uint uintX_t; @@ -522,8 +524,10 @@ unsigned addString(StringRef S, bool HashIt = true); void writeTo(uint8_t *Buf) override; 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; } + Kind getKind() const override { return StrTable; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == StrTable; + } private: const bool Dynamic; @@ -531,27 +535,26 @@ std::vector Strings; }; -template -class HashTableSection final : public OutputSectionBase { +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; } + Kind getKind() const override { return HashTable; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == HashTable; + } }; // Outputs GNU Hash section. For detailed explanation see: // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections template -class GnuHashTableSection final : public OutputSectionBase { +class GnuHashTableSection final : public OutputSectionBase { typedef typename ELFT::Off Elf_Off; typedef typename ELFT::Word Elf_Word; typedef typename ELFT::uint uintX_t; - typedef OutputSectionBase Base; public: GnuHashTableSection(); @@ -561,9 +564,9 @@ // 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; + Kind getKind() const override { return GnuHashTable; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == GnuHashTable; } private: @@ -587,9 +590,7 @@ unsigned Shift2; }; -template -class DynamicSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +template class DynamicSection final : public OutputSectionBase { typedef typename ELFT::Dyn Elf_Dyn; typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; @@ -604,12 +605,12 @@ struct Entry { int32_t Tag; union { - OutputSectionBase *OutSec; + OutputSectionBase *OutSec; uint64_t Val; const SymbolBody *Sym; }; enum KindT { SecAddr, SecSize, SymAddr, PlainInt } Kind; - Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr) + Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr) : Tag(Tag), OutSec(OutSec), Kind(Kind) {} Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {} Entry(int32_t Tag, const SymbolBody *Sym) @@ -625,8 +626,10 @@ 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; } + Kind getKind() const override { return Dynamic; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == Dynamic; + } private: void addEntries(); @@ -634,17 +637,16 @@ }; template -class MipsReginfoOutputSection final : public OutputSectionBase { +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; + void addSection(InputSectionData *S) override; + Kind getKind() const override { return MipsReginfo; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == MipsReginfo; } private: @@ -652,18 +654,17 @@ }; template -class MipsOptionsOutputSection final : public OutputSectionBase { +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; + void addSection(InputSectionData *S) override; + Kind getKind() const override { return MipsOptions; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == MipsOptions; } private: @@ -671,17 +672,16 @@ }; template -class MipsAbiFlagsOutputSection final : public OutputSectionBase { +class MipsAbiFlagsOutputSection final : public OutputSectionBase { typedef llvm::object::Elf_Mips_ABIFlags Elf_Mips_ABIFlags; - typedef OutputSectionBase Base; public: MipsAbiFlagsOutputSection(); void writeTo(uint8_t *Buf) override; - void addSection(InputSectionBase *S) override; - typename Base::Kind getKind() const override { return Base::MipsAbiFlags; } - static bool classof(const Base *B) { - return B->getKind() == Base::MipsAbiFlags; + void addSection(InputSectionData *S) override; + Kind getKind() const override { return MipsAbiFlags; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == MipsAbiFlags; } private: @@ -697,19 +697,17 @@ // Detailed info about internals can be found in Ian Lance Taylor's blog: // http://www.airs.com/blog/archives/460 (".eh_frame") // http://www.airs.com/blog/archives/462 (".eh_frame_hdr") -template -class EhFrameHeader final : public OutputSectionBase { +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; + Kind getKind() const override { return EHFrameHdr; } + static bool classof(const OutputSectionBase *B) { + return B->getKind() == EHFrameHdr; } private: @@ -739,7 +737,7 @@ static HashTableSection *HashTab; static OutputSection *Bss; static OutputSection *MipsRldMap; - static OutputSectionBase *Opd; + static OutputSectionBase *Opd; static uint8_t *OpdBuf; static PltSection *Plt; static RelocationSection *RelaDyn; @@ -753,12 +751,12 @@ static VersionTableSection *VerSym; static VersionNeedSection *VerNeed; static Elf_Phdr *TlsPhdr; - static OutputSectionBase *DebugInfo; - static OutputSectionBase *ElfHeader; - static OutputSectionBase *ProgramHeaders; - static OutputSectionBase *PreinitArray; - static OutputSectionBase *InitArray; - static OutputSectionBase *FiniArray; + static OutputSectionBase *DebugInfo; + static OutputSectionBase *ElfHeader; + static OutputSectionBase *ProgramHeaders; + static OutputSectionBase *PreinitArray; + static OutputSectionBase *InitArray; + static OutputSectionBase *FiniArray; }; template struct SectionKey { @@ -779,13 +777,13 @@ typedef typename elf::SectionKey Key; public: - std::pair *, bool> create(InputSectionBase *C, - StringRef OutsecName); - std::pair *, bool> + std::pair create(InputSectionBase *C, + StringRef OutsecName); + std::pair create(const SectionKey &Key, InputSectionBase *C); private: - llvm::SmallDenseMap *> Map; + llvm::SmallDenseMap Map; }; template uint64_t getHeaderSize() { @@ -805,7 +803,7 @@ template HashTableSection *Out::HashTab; template OutputSection *Out::Bss; template OutputSection *Out::MipsRldMap; -template OutputSectionBase *Out::Opd; +template OutputSectionBase *Out::Opd; template uint8_t *Out::OpdBuf; template PltSection *Out::Plt; template RelocationSection *Out::RelaDyn; @@ -819,12 +817,12 @@ template VersionTableSection *Out::VerSym; template VersionNeedSection *Out::VerNeed; template typename ELFT::Phdr *Out::TlsPhdr; -template OutputSectionBase *Out::DebugInfo; -template OutputSectionBase *Out::ElfHeader; -template OutputSectionBase *Out::ProgramHeaders; -template OutputSectionBase *Out::PreinitArray; -template OutputSectionBase *Out::InitArray; -template OutputSectionBase *Out::FiniArray; +template OutputSectionBase *Out::DebugInfo; +template OutputSectionBase *Out::ElfHeader; +template OutputSectionBase *Out::ProgramHeaders; +template OutputSectionBase *Out::PreinitArray; +template OutputSectionBase *Out::InitArray; +template OutputSectionBase *Out::FiniArray; } // namespace elf } // namespace lld Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -32,16 +32,15 @@ using namespace lld; using namespace lld::elf; -template -OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type, - uintX_t Flags) +OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type, + uint64_t Flags) : Name(Name) { this->Type = Type; this->Flags = Flags; this->Addralign = 1; } -template uint32_t OutputSectionBase::getPhdrFlags() const { +uint32_t OutputSectionBase::getPhdrFlags() const { uint32_t Ret = PF_R; if (Flags & SHF_WRITE) Ret |= PF_W; @@ -51,7 +50,7 @@ } template -void OutputSectionBase::writeHeaderTo(Elf_Shdr *Shdr) { +void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) { Shdr->sh_entsize = Entsize; Shdr->sh_addralign = Addralign; Shdr->sh_type = Type; @@ -66,7 +65,7 @@ template GdbIndexSection::GdbIndexSection() - : OutputSectionBase(".gdb_index", SHT_PROGBITS, 0) {} + : OutputSectionBase(".gdb_index", SHT_PROGBITS, 0) {} template void GdbIndexSection::parseDebugSections() { std::vector *> &IS = @@ -110,7 +109,7 @@ template GotPltSection::GotPltSection() - : OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { + : OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { this->Addralign = Target->GotPltEntrySize; } @@ -139,7 +138,7 @@ template GotSection::GotSection() - : OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { + : OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { if (Config->EMachine == EM_MIPS) this->Flags |= SHF_MIPS_GPREL; this->Addralign = Target->GotEntrySize; @@ -313,7 +312,7 @@ // Take into account MIPS GOT header. // See comment in the GotSection::writeTo. MipsPageEntries += 2; - for (const OutputSectionBase *OutSec : MipsOutSections) { + for (const OutputSectionBase *OutSec : MipsOutSections) { // Calculate an upper bound of MIPS GOT entries required to store page // addresses of local symbols. We assume the worst case - each 64kb // page of the output section has at least one GOT relocation against it. @@ -408,7 +407,7 @@ template PltSection::PltSection() - : OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) { + : OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) { this->Addralign = 16; } @@ -440,8 +439,7 @@ template RelocationSection::RelocationSection(StringRef Name, bool Sort) - : OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, - SHF_ALLOC), + : OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, SHF_ALLOC), Sort(Sort) { this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); this->Addralign = sizeof(uintX_t); @@ -504,7 +502,7 @@ template HashTableSection::HashTableSection() - : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) { + : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) { this->Entsize = sizeof(Elf_Word); this->Addralign = sizeof(Elf_Word); } @@ -550,7 +548,7 @@ template GnuHashTableSection::GnuHashTableSection() - : OutputSectionBase(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) { + : OutputSectionBase(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) { this->Entsize = ELFT::Is64Bits ? 0 : 4; this->Addralign = sizeof(uintX_t); } @@ -695,7 +693,7 @@ template DynamicSection::DynamicSection() - : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) { + : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) { this->Addralign = sizeof(uintX_t); this->Entsize = ELFT::Is64Bits ? 16 : 8; @@ -863,7 +861,7 @@ template EhFrameHeader::EhFrameHeader() - : OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {} + : OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {} // .eh_frame_hdr contains a binary search table of pointers to FDEs. // Each entry of the search table consists of two values, @@ -908,7 +906,7 @@ template OutputSection::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags) - : OutputSectionBase(Name, Type, Flags) { + : OutputSectionBase(Name, Type, Flags) { if (Type == SHT_RELA) this->Entsize = sizeof(Elf_Rela); else if (Type == SHT_REL) @@ -942,7 +940,7 @@ } template -void OutputSection::addSection(InputSectionBase *C) { +void OutputSection::addSection(InputSectionData *C) { assert(C->Live); auto *S = cast>(C); Sections.push_back(S); @@ -1071,7 +1069,7 @@ template EhOutputSection::EhOutputSection() - : OutputSectionBase(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {} + : OutputSectionBase(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {} // Search for an existing CIE record or create a new one. // CIE records from input object files are uniquified by their contents @@ -1156,7 +1154,7 @@ } template -void EhOutputSection::addSection(InputSectionBase *C) { +void EhOutputSection::addSection(InputSectionData *C) { auto *Sec = cast>(C); Sec->OutSec = this; this->updateAlignment(Sec->Alignment); @@ -1276,7 +1274,7 @@ template MergeOutputSection::MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags, uintX_t Alignment) - : OutputSectionBase(Name, Type, Flags), + : OutputSectionBase(Name, Type, Flags), Builder(StringTableBuilder::RAW, Alignment) {} template void MergeOutputSection::writeTo(uint8_t *Buf) { @@ -1284,7 +1282,7 @@ } template -void MergeOutputSection::addSection(InputSectionBase *C) { +void MergeOutputSection::addSection(InputSectionData *C) { auto *Sec = cast>(C); Sec->OutSec = this; this->updateAlignment(Sec->Alignment); @@ -1330,8 +1328,7 @@ template StringTableSection::StringTableSection(StringRef Name, bool Dynamic) - : OutputSectionBase(Name, SHT_STRTAB, - Dynamic ? (uintX_t)SHF_ALLOC : 0), + : OutputSectionBase(Name, SHT_STRTAB, Dynamic ? (uintX_t)SHF_ALLOC : 0), Dynamic(Dynamic) { // ELF string tables start with a NUL byte, so 1. this->Size = 1; @@ -1386,9 +1383,9 @@ template SymbolTableSection::SymbolTableSection( StringTableSection &StrTabSec) - : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab", - StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, - StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0), + : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab", + StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, + StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0), StrTabSec(StrTabSec) { this->Entsize = sizeof(Elf_Sym); this->Addralign = sizeof(uintX_t); @@ -1487,7 +1484,7 @@ ESym->st_shndx = SHN_ABS; ESym->st_value = Body.Value; } else { - const OutputSectionBase *OutSec = Section->OutSec; + const OutputSectionBase *OutSec = Section->OutSec; ESym->st_shndx = OutSec->SectionIndex; ESym->st_value = OutSec->Addr + Section->getOffset(Body); } @@ -1517,7 +1514,7 @@ ESym->setVisibility(Body->symbol()->Visibility); ESym->st_value = Body->getVA(); - if (const OutputSectionBase *OutSec = getOutputSection(Body)) + if (const OutputSectionBase *OutSec = getOutputSection(Body)) ESym->st_shndx = OutSec->SectionIndex; else if (isa>(Body)) ESym->st_shndx = SHN_ABS; @@ -1540,7 +1537,7 @@ } template -const OutputSectionBase * +const OutputSectionBase * SymbolTableSection::getOutputSection(SymbolBody *Sym) { switch (Sym->kind()) { case SymbolBody::DefinedSyntheticKind: @@ -1567,7 +1564,7 @@ template VersionDefinitionSection::VersionDefinitionSection() - : OutputSectionBase(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) { + : OutputSectionBase(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) { this->Addralign = sizeof(uint32_t); } @@ -1624,7 +1621,7 @@ template VersionTableSection::VersionTableSection() - : OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) { + : OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) { this->Addralign = sizeof(uint16_t); } @@ -1647,7 +1644,7 @@ template VersionNeedSection::VersionNeedSection() - : OutputSectionBase(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) { + : OutputSectionBase(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) { this->Addralign = sizeof(uint32_t); // Identifiers in verneed section start at 2 because 0 and 1 are reserved @@ -1726,7 +1723,7 @@ template MipsReginfoOutputSection::MipsReginfoOutputSection() - : OutputSectionBase(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) { + : OutputSectionBase(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) { this->Addralign = 4; this->Entsize = sizeof(Elf_Mips_RegInfo); this->Size = sizeof(Elf_Mips_RegInfo); @@ -1743,7 +1740,7 @@ } template -void MipsReginfoOutputSection::addSection(InputSectionBase *C) { +void MipsReginfoOutputSection::addSection(InputSectionData *C) { // Copy input object file's .reginfo gprmask to output. auto *S = cast>(C); GprMask |= S->Reginfo->ri_gprmask; @@ -1752,8 +1749,8 @@ template MipsOptionsOutputSection::MipsOptionsOutputSection() - : OutputSectionBase(".MIPS.options", SHT_MIPS_OPTIONS, - SHF_ALLOC | SHF_MIPS_NOSTRIP) { + : OutputSectionBase(".MIPS.options", SHT_MIPS_OPTIONS, + SHF_ALLOC | SHF_MIPS_NOSTRIP) { this->Addralign = 8; this->Entsize = 1; this->Size = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo); @@ -1775,7 +1772,7 @@ } template -void MipsOptionsOutputSection::addSection(InputSectionBase *C) { +void MipsOptionsOutputSection::addSection(InputSectionData *C) { auto *S = cast>(C); if (S->Reginfo) GprMask |= S->Reginfo->ri_gprmask; @@ -1784,7 +1781,7 @@ template MipsAbiFlagsOutputSection::MipsAbiFlagsOutputSection() - : OutputSectionBase(".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC) { + : OutputSectionBase(".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC) { this->Addralign = 8; this->Entsize = sizeof(Elf_Mips_ABIFlags); this->Size = sizeof(Elf_Mips_ABIFlags); @@ -1797,7 +1794,7 @@ } template -void MipsAbiFlagsOutputSection::addSection(InputSectionBase *C) { +void MipsAbiFlagsOutputSection::addSection(InputSectionData *C) { // Check compatibility and merge fields from input .MIPS.abiflags // to the output one. auto *S = cast>(C); @@ -1848,7 +1845,7 @@ } template -std::pair *, bool> +std::pair OutputSectionFactory::create(InputSectionBase *C, StringRef OutsecName) { SectionKey Key = createKey(C, OutsecName); @@ -1856,11 +1853,11 @@ } template -std::pair *, bool> +std::pair OutputSectionFactory::create(const SectionKey &Key, InputSectionBase *C) { uintX_t Flags = getOutFlags(C); - OutputSectionBase *&Sec = Map[Key]; + OutputSectionBase *&Sec = Map[Key]; if (Sec) { Sec->Flags |= Flags; return {Sec, false}; @@ -1923,10 +1920,11 @@ namespace lld { namespace elf { -template class OutputSectionBase; -template class OutputSectionBase; -template class OutputSectionBase; -template class OutputSectionBase; + +template void OutputSectionBase::writeHeaderTo(ELF32LE::Shdr *Shdr); +template void OutputSectionBase::writeHeaderTo(ELF32BE::Shdr *Shdr); +template void OutputSectionBase::writeHeaderTo(ELF64LE::Shdr *Shdr); +template void OutputSectionBase::writeHeaderTo(ELF64BE::Shdr *Shdr); template class EhFrameHeader; template class EhFrameHeader; Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -19,7 +19,7 @@ namespace lld { namespace elf { class Lazy; -template class OutputSectionBase; +class OutputSectionBase; struct Symbol; typedef llvm::CachedHashStringRef SymName; @@ -67,8 +67,8 @@ Symbol *addRegular(StringRef Name, uint8_t StOther, InputSectionBase *Section, uint8_t Binding, uint8_t Type, uintX_t Value); - Symbol *addSynthetic(StringRef N, OutputSectionBase *Section, - uintX_t Value, uint8_t StOther); + Symbol *addSynthetic(StringRef N, OutputSectionBase *Section, uintX_t Value, + uint8_t StOther); void addShared(SharedFile *F, StringRef Name, const Elf_Sym &Sym, const typename ELFT::Verdef *Verdef); Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -429,8 +429,7 @@ } template -Symbol *SymbolTable::addSynthetic(StringRef N, - OutputSectionBase *Section, +Symbol *SymbolTable::addSynthetic(StringRef N, OutputSectionBase *Section, uintX_t Value, uint8_t StOther) { Symbol *S; bool WasInserted; Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -31,7 +31,7 @@ class SymbolBody; template class ObjectFile; template class OutputSection; -template class OutputSectionBase; +class OutputSectionBase; template class SharedFile; struct Symbol; @@ -249,8 +249,7 @@ template class DefinedSynthetic : public Defined { public: typedef typename ELFT::uint uintX_t; - DefinedSynthetic(StringRef N, uintX_t Value, - OutputSectionBase *Section); + DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase *Section); static bool classof(const SymbolBody *S) { return S->kind() == SymbolBody::DefinedSyntheticKind; @@ -261,7 +260,7 @@ static const uintX_t SectionEnd = uintX_t(-1); uintX_t Value; - const OutputSectionBase *Section; + const OutputSectionBase *Section; }; class Undefined : public SymbolBody { Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -33,7 +33,7 @@ switch (Body.kind()) { case SymbolBody::DefinedSyntheticKind: { auto &D = cast>(Body); - const OutputSectionBase *Sec = D.Section; + const OutputSectionBase *Sec = D.Section; if (!Sec) return D.Value; if (D.Value == DefinedSynthetic::SectionEnd) @@ -216,7 +216,7 @@ template DefinedSynthetic::DefinedSynthetic(StringRef N, uintX_t Value, - OutputSectionBase *Section) + OutputSectionBase *Section) : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */), Value(Value), Section(Section) {} Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -17,24 +17,24 @@ namespace lld { namespace elf { class InputFile; -template class OutputSectionBase; +class OutputSectionBase; template class InputSectionBase; template class ObjectFile; template class SymbolTable; template void writeResult(); template void markLive(); -template bool isRelroSection(const OutputSectionBase *Sec); +template bool isRelroSection(const OutputSectionBase *Sec); // This describes a program header entry. // Each contains type, access flags and range of output sections that will be // placed in it. template struct PhdrEntry { PhdrEntry(unsigned Type, unsigned Flags); - void add(OutputSectionBase *Sec); + void add(OutputSectionBase *Sec); typename ELFT::Phdr H = {}; - OutputSectionBase *First = nullptr; - OutputSectionBase *Last = nullptr; + OutputSectionBase *First = nullptr; + OutputSectionBase *Last = nullptr; bool HasLMA = false; }; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -77,13 +77,13 @@ std::unique_ptr Buffer; - std::vector *> OutputSections; + std::vector OutputSections; OutputSectionFactory Factory; void addRelIpltSymbols(); void addStartEndSymbols(); - void addStartStopSymbols(OutputSectionBase *Sec); - OutputSectionBase *findSection(StringRef Name); + void addStartStopSymbols(OutputSectionBase *Sec); + OutputSectionBase *findSection(StringRef Name); std::vector Phdrs; @@ -221,9 +221,9 @@ Out::VerSym = make>(); Out::VerNeed = make>(); - Out::ElfHeader = make>("", 0, SHF_ALLOC); + Out::ElfHeader = make("", 0, SHF_ALLOC); Out::ElfHeader->Size = sizeof(Elf_Ehdr); - Out::ProgramHeaders = make>("", 0, SHF_ALLOC); + Out::ProgramHeaders = make("", 0, SHF_ALLOC); Out::ProgramHeaders->updateAlignment(sizeof(uintX_t)); if (needsInterpSection()) { @@ -390,11 +390,10 @@ .Default(1); } -template -bool elf::isRelroSection(const OutputSectionBase *Sec) { +template bool elf::isRelroSection(const OutputSectionBase *Sec) { if (!Config->ZRelro) return false; - typename ELFT::uint Flags = Sec->Flags; + uint64_t Flags = Sec->Flags; if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE)) return false; if (Flags & SHF_TLS) @@ -413,8 +412,8 @@ } template -static bool compareSectionsNonScript(const OutputSectionBase *A, - const OutputSectionBase *B) { +static bool compareSectionsNonScript(const OutputSectionBase *A, + const OutputSectionBase *B) { // Put .interp first because some loaders want to see that section // on the first page of the executable file when loaded into memory. bool AIsInterp = A->getName() == ".interp"; @@ -475,8 +474,8 @@ return BIsNoBits; // We place RelRo section before plain r/w ones. - bool AIsRelRo = isRelroSection(A); - bool BIsRelRo = isRelroSection(B); + bool AIsRelRo = isRelroSection(A); + bool BIsRelRo = isRelroSection(B); if (AIsRelRo != BIsRelRo) return AIsRelRo; @@ -491,8 +490,8 @@ // Output section ordering is determined by this function. template -static bool compareSections(const OutputSectionBase *A, - const OutputSectionBase *B) { +static bool compareSections(const OutputSectionBase *A, + const OutputSectionBase *B) { // For now, put sections mentioned in a linker script first. int AIndex = Script::X->getSectionIndex(A->getName()); int BIndex = Script::X->getSectionIndex(B->getName()); @@ -504,7 +503,7 @@ if (AInScript) return AIndex < BIndex; - return compareSectionsNonScript(A, B); + return compareSectionsNonScript(A, B); } // Program header entry @@ -514,7 +513,7 @@ H.p_flags = Flags; } -template void PhdrEntry::add(OutputSectionBase *Sec) { +template void PhdrEntry::add(OutputSectionBase *Sec) { Last = Sec; if (!First) First = Sec; @@ -524,9 +523,9 @@ } template -static Symbol * -addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec, - typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) { +static Symbol *addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec, + typename ELFT::uint Val, + uint8_t StOther = STV_HIDDEN) { SymbolBody *S = Symtab::X->find(Name); if (!S) return nullptr; @@ -545,11 +544,11 @@ if (Out::DynSymTab || !Out::RelaPlt) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; - addOptionalSynthetic(S, Out::RelaPlt, 0); + addOptionalSynthetic(S, Out::RelaPlt, 0); S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end"; - addOptionalSynthetic(S, Out::RelaPlt, - DefinedSynthetic::SectionEnd); + addOptionalSynthetic(S, Out::RelaPlt, + DefinedSynthetic::SectionEnd); } // The linker is expected to define some symbols depending on @@ -566,7 +565,7 @@ // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between // start of function and 'gp' pointer into GOT. Symbol *Sym = - addOptionalSynthetic("_gp_disp", Out::Got, MipsGPOffset); + addOptionalSynthetic("_gp_disp", Out::Got, MipsGPOffset); if (Sym) ElfSym::MipsGpDisp = Sym->body(); @@ -574,7 +573,7 @@ // pointer. This symbol is used in the code generated by .cpload pseudo-op // in case of using -mno-shared option. // https://sourceware.org/ml/binutils/2004-12/msg00094.html - addOptionalSynthetic("__gnu_local_gp", Out::Got, MipsGPOffset); + addOptionalSynthetic("__gnu_local_gp", Out::Got, MipsGPOffset); } // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol @@ -628,13 +627,13 @@ // Sort input sections by section name suffixes for // __attribute__((init_priority(N))). -template static void sortInitFini(OutputSectionBase *S) { +template static void sortInitFini(OutputSectionBase *S) { if (S) reinterpret_cast *>(S)->sortInitFini(); } // Sort input sections by the special rule for .ctors and .dtors. -template static void sortCtorsDtors(OutputSectionBase *S) { +template static void sortCtorsDtors(OutputSectionBase *S) { if (S) reinterpret_cast *>(S)->sortCtorsDtors(); } @@ -670,7 +669,7 @@ reportDiscarded(IS); return; } - OutputSectionBase *Sec; + OutputSectionBase *Sec; bool IsNew; StringRef OutsecName = getOutputSectionName(IS->Name); std::tie(Sec, IsNew) = Factory.create(IS, OutsecName); @@ -683,18 +682,18 @@ for (InputSectionBase *IS : Symtab::X->Sections) addInputSec(IS); - sortInitFini(findSection(".init_array")); - sortInitFini(findSection(".fini_array")); - sortCtorsDtors(findSection(".ctors")); - sortCtorsDtors(findSection(".dtors")); + sortInitFini(findSection(".init_array")); + sortInitFini(findSection(".fini_array")); + sortCtorsDtors(findSection(".ctors")); + sortCtorsDtors(findSection(".dtors")); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) Sec->assignOffsets(); } template -static bool canSharePtLoad(const OutputSectionBase &S1, - const OutputSectionBase &S2) { +static bool canSharePtLoad(const OutputSectionBase &S1, + const OutputSectionBase &S2) { if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC)) return false; @@ -746,15 +745,14 @@ auto I = OutputSections.begin(); auto E = OutputSections.end(); auto NonScriptI = - std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) { + std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) { return Script::X->getSectionIndex(S->getName()) == INT_MAX; }); while (NonScriptI != E) { - auto BestPos = - std::max_element(I, NonScriptI, [&](OutputSectionBase *&A, - OutputSectionBase *&B) { - bool ACanSharePtLoad = canSharePtLoad(**NonScriptI, *A); - bool BCanSharePtLoad = canSharePtLoad(**NonScriptI, *B); + auto BestPos = std::max_element( + I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) { + bool ACanSharePtLoad = canSharePtLoad(**NonScriptI, *A); + bool BCanSharePtLoad = canSharePtLoad(**NonScriptI, *B); if (ACanSharePtLoad != BCanSharePtLoad) return BCanSharePtLoad; @@ -791,7 +789,7 @@ // addresses of each section by section name. Add such symbols. if (!Config->Relocatable) { addStartEndSymbols(); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) addStartStopSymbols(Sec); } @@ -844,7 +842,7 @@ sortSections(); unsigned I = 1; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSectionBase *Sec : OutputSections) { Sec->SectionIndex = I++; Sec->ShName = Out::ShStrTab->addString(Sec->getName()); } @@ -857,7 +855,7 @@ // Fill other section headers. The dynamic table is finalized // at the end because some tags like RELSZ depend on result // of finalizing other sections. - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) if (Sec != Out::Dynamic) Sec->finalize(); @@ -866,7 +864,7 @@ // Now that all output offsets are fixed. Finalize mergeable sections // to fix their maps from input offsets to output offsets. - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) Sec->finalizePieces(); } @@ -886,7 +884,7 @@ // This function add Out::* sections to OutputSections. template void Writer::addPredefinedSections() { - auto Add = [&](OutputSectionBase *OS) { + auto Add = [&](OutputSectionBase *OS) { if (OS) OutputSections.push_back(OS); }; @@ -937,11 +935,11 @@ // The linker is expected to define SECNAME_start and SECNAME_end // symbols for a few sections. This function defines them. template void Writer::addStartEndSymbols() { - auto Define = [&](StringRef Start, StringRef End, - OutputSectionBase *OS) { + auto Define = [&](StringRef Start, StringRef End, OutputSectionBase *OS) { // These symbols resolve to the image base if the section does not exist. - addOptionalSynthetic(Start, OS, 0); - addOptionalSynthetic(End, OS, OS ? DefinedSynthetic::SectionEnd : 0); + addOptionalSynthetic(Start, OS, 0); + addOptionalSynthetic(End, OS, + OS ? DefinedSynthetic::SectionEnd : 0); }; Define("__preinit_array_start", "__preinit_array_end", @@ -949,7 +947,7 @@ Define("__init_array_start", "__init_array_end", Out::InitArray); Define("__fini_array_start", "__fini_array_end", Out::FiniArray); - if (OutputSectionBase *Sec = findSection(".ARM.exidx")) + if (OutputSectionBase *Sec = findSection(".ARM.exidx")) Define("__exidx_start", "__exidx_end", Sec); } @@ -959,24 +957,24 @@ // respectively. This is not requested by the ELF standard, but GNU ld and // gold provide the feature, and used by many programs. template -void Writer::addStartStopSymbols(OutputSectionBase *Sec) { +void Writer::addStartStopSymbols(OutputSectionBase *Sec) { StringRef S = Sec->getName(); if (!isValidCIdentifier(S)) return; - addOptionalSynthetic(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT); - addOptionalSynthetic(Saver.save("__stop_" + S), Sec, - DefinedSynthetic::SectionEnd, STV_DEFAULT); + addOptionalSynthetic(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT); + addOptionalSynthetic(Saver.save("__stop_" + S), Sec, + DefinedSynthetic::SectionEnd, STV_DEFAULT); } template -OutputSectionBase *Writer::findSection(StringRef Name) { - for (OutputSectionBase *Sec : OutputSections) +OutputSectionBase *Writer::findSection(StringRef Name) { + for (OutputSectionBase *Sec : OutputSections) if (Sec->getName() == Name) return Sec; return nullptr; } -template static bool needsPtLoad(OutputSectionBase *Sec) { +template static bool needsPtLoad(OutputSectionBase *Sec) { if (!(Sec->Flags & SHF_ALLOC)) return false; @@ -1013,7 +1011,7 @@ Hdr.add(Out::ProgramHeaders); // PT_INTERP must be the second entry if exists. - if (OutputSectionBase *Sec = findSection(".interp")) { + if (OutputSectionBase *Sec = findSection(".interp")) { Phdr &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags()); Hdr.add(Sec); } @@ -1030,7 +1028,7 @@ Phdr RelRo(PT_GNU_RELRO, PF_R); Phdr Note(PT_NOTE, PF_R); Phdr ARMExidx(PT_ARM_EXIDX, PF_R); - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSectionBase *Sec : OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -1040,7 +1038,7 @@ if (Sec->Flags & SHF_TLS) TlsHdr.add(Sec); - if (!needsPtLoad(Sec)) + if (!needsPtLoad(Sec)) continue; // Segments are contiguous memory regions that has the same attributes @@ -1056,7 +1054,7 @@ Load->add(Sec); - if (isRelroSection(Sec)) + if (isRelroSection(Sec)) RelRo.add(Sec); if (Sec->Type == SHT_NOTE) Note.add(Sec); @@ -1088,7 +1086,7 @@ // PT_OPENBSD_RANDOMIZE specifies the location and size of a part of the // memory image of the program that must be filled with random data before any // code in the object is executed. - if (OutputSectionBase *Sec = findSection(".openbsd.randomdata")) { + if (OutputSectionBase *Sec = findSection(".openbsd.randomdata")) { Phdr &Hdr = *AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags()); Hdr.add(Sec); } @@ -1133,8 +1131,8 @@ auto I = std::find(OutputSections.begin(), End, P.Last); if (I == End || (I + 1) == End) continue; - OutputSectionBase *Sec = *(I + 1); - if (needsPtLoad(Sec)) + OutputSectionBase *Sec = *(I + 1); + if (needsPtLoad(Sec)) Sec->PageAlign = true; } } @@ -1154,7 +1152,7 @@ template void Writer::assignAddresses() { uintX_t VA = Config->ImageBase + getHeaderSize(); uintX_t ThreadBssOffset = 0; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSectionBase *Sec : OutputSections) { uintX_t Alignment = Sec->Addralign; if (Sec->PageAlign) Alignment = std::max(Alignment, Config->MaxPageSize); @@ -1164,7 +1162,7 @@ VA = I->second; // We only assign VAs to allocated sections. - if (needsPtLoad(Sec)) { + if (needsPtLoad(Sec)) { VA = alignTo(VA, Alignment); Sec->Addr = VA; VA += Sec->Size; @@ -1182,13 +1180,13 @@ // virtual address (modulo the page size) so that the loader can load // executables without any address adjustment. template -static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) { +static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) { uintX_t Alignment = Sec->Addralign; if (Sec->PageAlign) Alignment = std::max(Alignment, Config->MaxPageSize); Off = alignTo(Off, Alignment); - OutputSectionBase *First = Sec->FirstInPtLoad; + OutputSectionBase *First = Sec->FirstInPtLoad; // If the section is not in a PT_LOAD, we have no other constraint. if (!First) return Off; @@ -1201,7 +1199,7 @@ } template -void setOffset(OutputSectionBase *Sec, uintX_t &Off) { +void setOffset(OutputSectionBase *Sec, uintX_t &Off) { if (Sec->Type == SHT_NOBITS) { Sec->Offset = Off; return; @@ -1214,20 +1212,20 @@ template void Writer::assignFileOffsetsBinary() { uintX_t Off = 0; - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) if (Sec->Flags & SHF_ALLOC) - setOffset(Sec, Off); + setOffset(Sec, Off); FileSize = alignTo(Off, sizeof(uintX_t)); } // Assign file offsets to output sections. template void Writer::assignFileOffsets() { uintX_t Off = 0; - setOffset(Out::ElfHeader, Off); - setOffset(Out::ProgramHeaders, Off); + setOffset(Out::ElfHeader, Off); + setOffset(Out::ProgramHeaders, Off); - for (OutputSectionBase *Sec : OutputSections) - setOffset(Sec, Off); + for (OutputSectionBase *Sec : OutputSections) + setOffset(Sec, Off); SectionHeaderOff = alignTo(Off, sizeof(uintX_t)); FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); @@ -1238,8 +1236,8 @@ template void Writer::setPhdrs() { for (Phdr &P : Phdrs) { Elf_Phdr &H = P.H; - OutputSectionBase *First = P.First; - OutputSectionBase *Last = P.Last; + OutputSectionBase *First = P.First; + OutputSectionBase *Last = P.Last; if (First) { H.p_filesz = Last->Offset - First->Offset; if (Last->Type != SHT_NOBITS) @@ -1361,8 +1359,8 @@ // Write the section header table. Note that the first table entry is null. auto *SHdrs = reinterpret_cast(Buf + EHdr->e_shoff); - for (OutputSectionBase *Sec : OutputSections) - Sec->writeHeaderTo(++SHdrs); + for (OutputSectionBase *Sec : OutputSections) + Sec->writeHeaderTo(++SHdrs); } template void Writer::openFile() { @@ -1377,7 +1375,7 @@ template void Writer::writeSectionsBinary() { uint8_t *Buf = Buffer->getBufferStart(); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) if (Sec->Flags & SHF_ALLOC) Sec->writeTo(Buf + Sec->Offset); } @@ -1449,11 +1447,11 @@ Out::Opd->writeTo(Buf + Out::Opd->Offset); } - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) if (Sec != Out::Opd && Sec != Out::EhFrameHdr) Sec->writeTo(Buf + Sec->Offset); - OutputSectionBase *ARMExidx = findSection(".ARM.exidx"); + OutputSectionBase *ARMExidx = findSection(".ARM.exidx"); if (!Config->Relocatable) if (auto *OS = dyn_cast_or_null>(ARMExidx)) sortARMExidx(Buf + OS->Offset, OS->Addr, OS->Size); @@ -1484,10 +1482,10 @@ template struct elf::PhdrEntry; template struct elf::PhdrEntry; -template bool elf::isRelroSection(const OutputSectionBase *); -template bool elf::isRelroSection(const OutputSectionBase *); -template bool elf::isRelroSection(const OutputSectionBase *); -template bool elf::isRelroSection(const OutputSectionBase *); +template bool elf::isRelroSection(const OutputSectionBase *); +template bool elf::isRelroSection(const OutputSectionBase *); +template bool elf::isRelroSection(const OutputSectionBase *); +template bool elf::isRelroSection(const OutputSectionBase *); template void elf::reportDiscarded(InputSectionBase *); template void elf::reportDiscarded(InputSectionBase *);