From: Rafael Espindola Date: Wed, 9 Nov 2016 23:23:45 +0000 (+0000) Subject: Make OutputSectionBase a class instead of class template. X-Git-Tag: llvmorg-4.0.0-rc1~5079 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e08e78df6dda162f8dba15d6f17905607edd3620;p=platform%2Fupstream%2Fllvm.git Make OutputSectionBase a class instead of class template. The disadvantage is that we use uint64_t instad of uint32_t for some value in 32 bit files. The advantage is a substantially simpler code, faster builds and less code duplication. llvm-svn: 286414 --- diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 89a5fd7..e6766ae 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -29,7 +29,7 @@ template class ICF; 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 @@ public: 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, diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 5204c5c..e911fa5 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -229,7 +229,7 @@ void LinkerScript::computeInputSections(InputSectionDescription *I) { // 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 @@ template 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 @@ void LinkerScript::createSections(OutputSectionFactory &Factory) { // 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 @@ static void assignSectionSymbol(SymbolAssignment *Cmd, 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::flush() { } template -void LinkerScript::switchTo(OutputSectionBase *Sec) { +void LinkerScript::switchTo(OutputSectionBase *Sec) { if (CurOutSec == Sec) return; if (AlreadyOutputOS.count(Sec)) @@ -435,7 +434,7 @@ void LinkerScript::switchTo(OutputSectionBase *Sec) { 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 void LinkerScript::process(BaseCommand &Base) { } 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 @@ template 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 @@ void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) { .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 @@ template void LinkerScript::adjustSectionsBeforeSorting() { 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 @@ template void LinkerScript::adjustSectionsBeforeSorting() { 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 @@ void LinkerScript::assignAddresses(std::vector> &Phdrs) { // 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 @@ void LinkerScript::assignAddresses(std::vector> &Phdrs) { 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 @@ void LinkerScript::assignAddresses(std::vector> &Phdrs) { } 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 @@ std::vector> LinkerScript::createPhdrs() { } // 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 bool LinkerScript::hasPhdrsCommands() { 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 @@ uint64_t LinkerScript::getOutputSectionAddress(StringRef Name) { 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 @@ uint64_t LinkerScript::getOutputSectionLMA(StringRef Name) { 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 @@ uint64_t LinkerScript::getOutputSectionSize(StringRef Name) { 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); diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index a3f0c2d..1840978 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -32,7 +32,7 @@ class ScriptParser; class SymbolBody; template class InputSectionBase; template class InputSection; -template class OutputSectionBase; +class OutputSectionBase; template class OutputSectionFactory; class InputSectionData; @@ -240,7 +240,7 @@ public: bool isDefined(StringRef S) override; bool isAbsolute(StringRef S) override; - std::vector *> *OutputSections; + std::vector *OutputSections; int getSectionIndex(StringRef Name); @@ -262,13 +262,13 @@ private: 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; }; diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 02224fe..4df316e 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -32,16 +32,15 @@ using namespace llvm::ELF; 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 uint32_t OutputSectionBase::getPhdrFlags() const { } 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 @@ void OutputSectionBase::writeHeaderTo(Elf_Shdr *Shdr) { 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 void GdbIndexSection::writeTo(uint8_t *Buf) { 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 void GotPltSection::writeTo(uint8_t *Buf) { 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 @@ template void GotSection::finalize() { // 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 void GotSection::writeTo(uint8_t *Buf) { 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 void PltSection::finalize() { 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 void RelocationSection::finalize() { 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 @@ static uint32_t hashGnu(StringRef Name) { 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 @@ static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; } 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 void DynamicSection::writeTo(uint8_t *Buf) { 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, @@ -925,7 +923,7 @@ template static uint64_t getEntsize(uint32_t Type) { template OutputSection::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags) - : OutputSectionBase(Name, Type, Flags) { + : OutputSectionBase(Name, Type, Flags) { this->Entsize = getEntsize(Type); } @@ -956,7 +954,7 @@ template void OutputSection::finalize() { } template -void OutputSection::addSection(InputSectionBase *C) { +void OutputSection::addSection(InputSectionData *C) { assert(C->Live); auto *S = cast>(C); Sections.push_back(S); @@ -1085,7 +1083,7 @@ template void OutputSection::writeTo(uint8_t *Buf) { 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 @@ -1170,7 +1168,7 @@ void EhOutputSection::addSectionAux(EhInputSection *Sec, } template -void EhOutputSection::addSection(InputSectionBase *C) { +void EhOutputSection::addSection(InputSectionData *C) { auto *Sec = cast>(C); Sec->OutSec = this; this->updateAlignment(Sec->Alignment); @@ -1290,7 +1288,7 @@ template void EhOutputSection::writeTo(uint8_t *Buf) { 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) { @@ -1298,7 +1296,7 @@ template void MergeOutputSection::writeTo(uint8_t *Buf) { } template -void MergeOutputSection::addSection(InputSectionBase *C) { +void MergeOutputSection::addSection(InputSectionData *C) { auto *Sec = cast>(C); Sec->OutSec = this; this->updateAlignment(Sec->Alignment); @@ -1344,8 +1342,7 @@ template void MergeOutputSection::finalizePieces() { 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; @@ -1400,9 +1397,9 @@ template uint32_t DynamicReloc::getSymIndex() const { 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); @@ -1501,7 +1498,7 @@ void SymbolTableSection::writeLocalSymbols(uint8_t *&Buf) { 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); } @@ -1531,7 +1528,7 @@ void SymbolTableSection::writeGlobalSymbols(uint8_t *Buf) { 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; @@ -1554,7 +1551,7 @@ void SymbolTableSection::writeGlobalSymbols(uint8_t *Buf) { } template -const OutputSectionBase * +const OutputSectionBase * SymbolTableSection::getOutputSection(SymbolBody *Sym) { switch (Sym->kind()) { case SymbolBody::DefinedSyntheticKind: @@ -1581,7 +1578,7 @@ SymbolTableSection::getOutputSection(SymbolBody *Sym) { 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); } @@ -1638,7 +1635,7 @@ void VersionDefinitionSection::writeTo(uint8_t *Buf) { template VersionTableSection::VersionTableSection() - : OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) { + : OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) { this->Addralign = sizeof(uint16_t); } @@ -1661,7 +1658,7 @@ template void VersionTableSection::writeTo(uint8_t *Buf) { 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 @@ -1764,7 +1761,7 @@ static SectionKey createKey(InputSectionBase *C, } template -std::pair *, bool> +std::pair OutputSectionFactory::create(InputSectionBase *C, StringRef OutsecName) { SectionKey Key = createKey(C, OutsecName); @@ -1772,11 +1769,11 @@ OutputSectionFactory::create(InputSectionBase *C, } 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}; @@ -1830,10 +1827,11 @@ template struct DenseMapInfo>; 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; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 7ca4399..bc4f81a 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -42,10 +42,8 @@ template class DefinedRegular; // 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, @@ -66,15 +64,15 @@ public: 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; } @@ -82,7 +80,7 @@ public: uint32_t getPhdrFlags() const; - void updateAlignment(uintX_t Alignment) { + void updateAlignment(uint64_t Alignment) { if (Alignment > Addralign) Addralign = Alignment; } @@ -97,7 +95,7 @@ public: // 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() {} @@ -108,21 +106,20 @@ public: 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; @@ -146,8 +143,7 @@ private: 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: @@ -163,8 +159,10 @@ public: 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 @@ -192,7 +190,7 @@ private: 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 @@ -213,10 +211,8 @@ private: 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(); @@ -224,15 +220,16 @@ public: 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: @@ -241,8 +238,10 @@ public: 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; @@ -258,7 +257,7 @@ public: : 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), @@ -267,14 +266,14 @@ public: 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; @@ -286,8 +285,8 @@ struct SymbolTableEntry { }; template -class SymbolTableSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +class SymbolTableSection final : public OutputSectionBase { + typedef OutputSectionBase Base; public: typedef typename ELFT::Shdr Elf_Shdr; @@ -313,7 +312,7 @@ private: 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; @@ -328,17 +327,18 @@ private: // 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); @@ -353,16 +353,17 @@ private: // 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 @@ -371,8 +372,7 @@ public: // 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; @@ -389,16 +389,16 @@ public: 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); @@ -407,9 +407,11 @@ public: 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; @@ -417,9 +419,7 @@ private: 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; @@ -428,33 +428,36 @@ public: 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; @@ -467,13 +470,11 @@ struct CieRecord { }; // 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(); @@ -481,9 +482,11 @@ public: 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; @@ -509,8 +512,7 @@ private: }; template -class StringTableSection final : public OutputSectionBase { - typedef OutputSectionBase Base; +class StringTableSection final : public OutputSectionBase { public: typedef typename ELFT::uint uintX_t; @@ -518,8 +520,10 @@ public: 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; @@ -527,27 +531,26 @@ private: 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(); @@ -557,9 +560,9 @@ public: // 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: @@ -583,9 +586,7 @@ private: 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; @@ -600,12 +601,12 @@ class DynamicSection final : public OutputSectionBase { 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) @@ -621,8 +622,10 @@ public: 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(); @@ -638,19 +641,17 @@ private: // 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: @@ -680,7 +681,7 @@ template struct Out { 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; @@ -694,12 +695,12 @@ template struct Out { 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 { @@ -720,13 +721,13 @@ template class OutputSectionFactory { 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() { @@ -746,7 +747,7 @@ template GotSection *Out::Got; 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; @@ -760,12 +761,12 @@ template VersionDefinitionSection *Out::VerDef; 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 diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 38a2905..6d55bbb 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -429,8 +429,7 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, } 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; diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 9587309..7683706 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/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 @@ public: 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); diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 9b1aa5d..bfff4e4 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -33,7 +33,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, 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 @@ Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type, template DefinedSynthetic::DefinedSynthetic(StringRef N, uintX_t Value, - OutputSectionBase *Section) + OutputSectionBase *Section) : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */), Value(Value), Section(Section) {} diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index c5bee89..cfb9897 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -31,7 +31,7 @@ class LazyObjectFile; class SymbolBody; template class ObjectFile; template class OutputSection; -template class OutputSectionBase; +class OutputSectionBase; template class SharedFile; struct Symbol; @@ -249,8 +249,7 @@ InputSectionBase *DefinedRegular::NullInputSection; 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 @@ public: static const uintX_t SectionEnd = uintX_t(-1); uintX_t Value; - const OutputSectionBase *Section; + const OutputSectionBase *Section; }; class Undefined : public SymbolBody { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7e37064..662baf4 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -77,13 +77,13 @@ private: 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 @@ template void Writer::createSyntheticSections() { 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()) { @@ -411,11 +411,10 @@ static int getPPC64SectionRank(StringRef SectionName) { .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) @@ -434,8 +433,8 @@ bool elf::isRelroSection(const OutputSectionBase *Sec) { } 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"; @@ -496,8 +495,8 @@ static bool compareSectionsNonScript(const OutputSectionBase *A, 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; @@ -512,8 +511,8 @@ static bool compareSectionsNonScript(const OutputSectionBase *A, // 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()); @@ -525,7 +524,7 @@ static bool compareSections(const OutputSectionBase *A, if (AInScript) return AIndex < BIndex; - return compareSectionsNonScript(A, B); + return compareSectionsNonScript(A, B); } // Program header entry @@ -535,7 +534,7 @@ PhdrEntry::PhdrEntry(unsigned Type, unsigned Flags) { H.p_flags = Flags; } -template void PhdrEntry::add(OutputSectionBase *Sec) { +template void PhdrEntry::add(OutputSectionBase *Sec) { Last = Sec; if (!First) First = Sec; @@ -545,9 +544,9 @@ template void PhdrEntry::add(OutputSectionBase *Sec) { } 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; @@ -566,11 +565,11 @@ template void Writer::addRelIpltSymbols() { 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 @@ -587,7 +586,7 @@ template void Writer::addReservedSymbols() { // 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(); @@ -595,7 +594,7 @@ template void Writer::addReservedSymbols() { // 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 @@ -649,13 +648,13 @@ template void Writer::addReservedSymbols() { // 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(); } @@ -691,7 +690,7 @@ void Writer::addInputSec(InputSectionBase *IS) { reportDiscarded(IS); return; } - OutputSectionBase *Sec; + OutputSectionBase *Sec; bool IsNew; StringRef OutsecName = getOutputSectionName(IS->Name); std::tie(Sec, IsNew) = Factory.create(IS, OutsecName); @@ -704,18 +703,18 @@ template void Writer::createSections() { 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; @@ -767,15 +766,14 @@ template void Writer::sortSections() { 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; @@ -812,7 +810,7 @@ template void Writer::finalizeSections() { // addresses of each section by section name. Add such symbols. if (!Config->Relocatable) { addStartEndSymbols(); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSectionBase *Sec : OutputSections) addStartStopSymbols(Sec); } @@ -865,7 +863,7 @@ template void Writer::finalizeSections() { sortSections(); unsigned I = 1; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSectionBase *Sec : OutputSections) { Sec->SectionIndex = I++; Sec->ShName = Out::ShStrTab->addString(Sec->getName()); } @@ -878,7 +876,7 @@ template void Writer::finalizeSections() { // 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(); @@ -887,7 +885,7 @@ template void Writer::finalizeSections() { // 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(); } @@ -907,7 +905,7 @@ template bool Writer::needsGot() { // 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); }; @@ -958,11 +956,11 @@ template void Writer::addPredefinedSections() { // 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", @@ -970,7 +968,7 @@ template void Writer::addStartEndSymbols() { 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); } @@ -980,24 +978,24 @@ template void Writer::addStartEndSymbols() { // 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; @@ -1034,7 +1032,7 @@ template std::vector> Writer::createPhdrs() { 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); } @@ -1051,7 +1049,7 @@ template std::vector> Writer::createPhdrs() { 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; @@ -1061,7 +1059,7 @@ template std::vector> Writer::createPhdrs() { 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 @@ -1077,7 +1075,7 @@ template std::vector> Writer::createPhdrs() { Load->add(Sec); - if (isRelroSection(Sec)) + if (isRelroSection(Sec)) RelRo.add(Sec); if (Sec->Type == SHT_NOTE) Note.add(Sec); @@ -1109,7 +1107,7 @@ template std::vector> Writer::createPhdrs() { // 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); } @@ -1154,8 +1152,8 @@ template void Writer::fixSectionAlignments() { 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; } } @@ -1175,7 +1173,7 @@ template void Writer::fixHeaders() { 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); @@ -1185,7 +1183,7 @@ template void Writer::assignAddresses() { 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; @@ -1203,13 +1201,13 @@ template void Writer::assignAddresses() { // 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; @@ -1222,7 +1220,7 @@ static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) { } template -void setOffset(OutputSectionBase *Sec, uintX_t &Off) { +void setOffset(OutputSectionBase *Sec, uintX_t &Off) { if (Sec->Type == SHT_NOBITS) { Sec->Offset = Off; return; @@ -1235,20 +1233,20 @@ void setOffset(OutputSectionBase *Sec, uintX_t &Off) { 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); @@ -1259,8 +1257,8 @@ template void Writer::assignFileOffsets() { 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) @@ -1382,8 +1380,8 @@ template void Writer::writeHeader() { // 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() { @@ -1398,7 +1396,7 @@ template void Writer::openFile() { 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); } @@ -1477,11 +1475,11 @@ template void Writer::writeSections() { 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); @@ -1512,10 +1510,10 @@ template struct elf::PhdrEntry; 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 *); diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h index 3b6c6e5..4e353ac 100644 --- a/lld/ELF/Writer.h +++ b/lld/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; };