diff options
Diffstat (limited to 'lld')
-rw-r--r-- | lld/ELF/InputSection.cpp | 10 | ||||
-rw-r--r-- | lld/ELF/InputSection.h | 7 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 54 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.h | 28 | ||||
-rw-r--r-- | lld/ELF/MapFile.cpp | 21 | ||||
-rw-r--r-- | lld/ELF/MapFile.h | 2 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 99 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 92 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 29 | ||||
-rw-r--r-- | lld/ELF/Relocations.h | 4 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.h | 5 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 8 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 16 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 10 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/Thunks.h | 1 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 180 | ||||
-rw-r--r-- | lld/ELF/Writer.h | 14 |
20 files changed, 271 insertions, 317 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 6e9a7d78401..b80c206ed8b 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -118,7 +118,7 @@ uint64_t InputSectionBase::getOffset(uint64_t Offset) const { } template <class ELFT> -OutputSectionBase *InputSectionBase::getOutputSection() const { +OutputSection *InputSectionBase::getOutputSection() const { if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(this)) return MS->MergeSec ? MS->MergeSec->OutSec : nullptr; if (auto *EH = dyn_cast<EhInputSection<ELFT>>(this)) @@ -827,10 +827,10 @@ template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF32BE>() const; template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64LE>() const; template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64BE>() const; -template OutputSectionBase *InputSectionBase::getOutputSection<ELF32LE>() const; -template OutputSectionBase *InputSectionBase::getOutputSection<ELF32BE>() const; -template OutputSectionBase *InputSectionBase::getOutputSection<ELF64LE>() const; -template OutputSectionBase *InputSectionBase::getOutputSection<ELF64BE>() const; +template OutputSection *InputSectionBase::getOutputSection<ELF32LE>() const; +template OutputSection *InputSectionBase::getOutputSection<ELF32BE>() const; +template OutputSection *InputSectionBase::getOutputSection<ELF64LE>() const; +template OutputSection *InputSectionBase::getOutputSection<ELF64BE>() const; template InputSectionBase *InputSection::getRelocatedSection<ELF32LE>(); template InputSectionBase *InputSection::getRelocatedSection<ELF32BE>(); diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 6cb895bb5a4..39f799a3761 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -31,8 +31,7 @@ template <class ELFT> class DefinedRegular; template <class ELFT> class EhFrameSection; template <class ELFT> class MergeSyntheticSection; template <class ELFT> class ObjectFile; -template <class ELFT> class OutputSection; -class OutputSectionBase; +class OutputSection; // This corresponds to a section of an input file. class InputSectionBase { @@ -78,7 +77,7 @@ public: uint64_t Entsize, uint32_t Link, uint32_t Info, uint64_t Addralign, ArrayRef<uint8_t> Data, StringRef Name, Kind SectionKind); - OutputSectionBase *OutSec = nullptr; + OutputSection *OutSec = nullptr; // Relocations that refer to this section. const void *FirstRelocation = nullptr; @@ -110,7 +109,7 @@ public: // Returns the size of this section (even if this is a common or BSS.) template <class ELFT> size_t getSize() const; - template <class ELFT> OutputSectionBase *getOutputSection() const; + template <class ELFT> OutputSection *getOutputSection() const; template <class ELFT> ObjectFile<ELFT> *getFile() const; diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 5e3f0cd0de7..5e06050859f 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -72,7 +72,7 @@ template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) { template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) { Symbol *Sym; uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; - const OutputSectionBase *Sec = + const OutputSection *Sec = ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section(); std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert( Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false, @@ -397,7 +397,7 @@ void LinkerScript<ELFT>::addOrphanSections( Factory.addInputSec(S, getOutputSectionName(S->Name)); } -template <class ELFT> static bool isTbss(OutputSectionBase *Sec) { +template <class ELFT> static bool isTbss(OutputSection *Sec) { return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS; } @@ -438,16 +438,11 @@ template <class ELFT> void LinkerScript<ELFT>::output(InputSection *S) { template <class ELFT> void LinkerScript<ELFT>::flush() { if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) return; - if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { - for (InputSection *I : OutSec->Sections) - output(I); - } else { - Dot += CurOutSec->Size; - } + for (InputSection *I : CurOutSec->Sections) + output(I); } -template <class ELFT> -void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) { +template <class ELFT> void LinkerScript<ELFT>::switchTo(OutputSection *Sec) { if (CurOutSec == Sec) return; if (AlreadyOutputOS.count(Sec)) @@ -512,12 +507,12 @@ template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { } template <class ELFT> -static OutputSectionBase * -findSection(StringRef Name, const std::vector<OutputSectionBase *> &Sections) { +static OutputSection * +findSection(StringRef Name, const std::vector<OutputSection *> &Sections) { auto End = Sections.end(); - auto HasName = [=](OutputSectionBase *Sec) { return Sec->Name == Name; }; + auto HasName = [=](OutputSection *Sec) { return Sec->Name == Name; }; auto I = std::find_if(Sections.begin(), End, HasName); - std::vector<OutputSectionBase *> Ret; + std::vector<OutputSection *> Ret; if (I == End) return nullptr; assert(std::find_if(I + 1, End, HasName) == End); @@ -529,7 +524,7 @@ findSection(StringRef Name, const std::vector<OutputSectionBase *> &Sections) { // returned. Otherwise, a nullptr is returned. template <class ELFT> MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd, - OutputSectionBase *Sec) { + OutputSection *Sec) { // If a memory region name was specified in the output section command, // then try to find that region first. if (!Cmd->MemoryRegionName.empty()) { @@ -568,7 +563,7 @@ void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { uintX_t D = Dot; LMAOffset = [=] { return Cmd->LMAExpr(D) - D; }; } - OutputSectionBase *Sec = findSection<ELFT>(Cmd->Name, *OutputSections); + OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections); if (!Sec) return; @@ -634,8 +629,7 @@ template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); if (!Cmd) continue; - if (OutputSectionBase *Sec = - findSection<ELFT>(Cmd->Name, *OutputSections)) { + if (OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections)) { Flags = Sec->Flags; Type = Sec->Type; continue; @@ -644,7 +638,7 @@ template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { if (isAllSectionDescription(*Cmd)) continue; - auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags); + auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags); OutputSections->push_back(OutSec); } } @@ -751,7 +745,7 @@ template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() { ++CmdIndex; } - for (OutputSectionBase *Sec : *OutputSections) { + for (OutputSection *Sec : *OutputSections) { StringRef Name = Sec->Name; // Find the last spot where we can insert a command and still get the @@ -794,7 +788,7 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) { // To handle that, create a dummy aether section that fills the void before // the linker scripts switches to another section. It has an index of one // which will map to whatever the first actual section is. - auto *Aether = make<OutputSectionBase>("", 0, SHF_ALLOC); + auto *Aether = make<OutputSection>("", 0, SHF_ALLOC); Aether->SectionIndex = 1; switchTo(Aether); @@ -814,7 +808,7 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) { } uintX_t MinVA = std::numeric_limits<uintX_t>::max(); - for (OutputSectionBase *Sec : *OutputSections) { + for (OutputSection *Sec : *OutputSections) { if (Sec->Flags & SHF_ALLOC) MinVA = std::min<uint64_t>(MinVA, Sec->Addr); else @@ -846,7 +840,7 @@ template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() { } // Add output sections to program headers. - for (OutputSectionBase *Sec : *OutputSections) { + for (OutputSection *Sec : *OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -936,11 +930,11 @@ template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { } template <class ELFT> -const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc, - StringRef Name) { - static OutputSectionBase FakeSec("", 0, 0); +const OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc, + StringRef Name) { + static OutputSection FakeSec("", 0, 0); - for (OutputSectionBase *Sec : *OutputSections) + for (OutputSection *Sec : *OutputSections) if (Sec->Name == Name) return Sec; @@ -956,7 +950,7 @@ const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc, // be empty. That is why this function is different from getOutputSection(). template <class ELFT> uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { - for (OutputSectionBase *Sec : *OutputSections) + for (OutputSection *Sec : *OutputSections) if (Sec->Name == Name) return Sec->Size; return 0; @@ -988,7 +982,7 @@ template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) { // specific section but isn't absolute at the same time, so we try // to find suitable section for it as well. template <class ELFT> -const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) { +const OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) { if (SymbolBody *Sym = Symtab<ELFT>::X->find(S)) return SymbolTableSection<ELFT>::getOutputSection(Sym); return CurOutSec; @@ -1646,7 +1640,7 @@ Expr ScriptParser::readExpr() { static Expr combine(StringRef Op, Expr L, Expr R) { auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); }; auto GetOutSec = [=] { - const OutputSectionBase *S = L.Section(); + const OutputSection *S = L.Section(); return S ? S : R.Section(); }; diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index c8b967b2e37..4dbd5af919c 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -33,7 +33,7 @@ class ScriptParser; class SymbolBody; class InputSectionBase; class InputSection; -class OutputSectionBase; +class OutputSection; template <class ELFT> class OutputSectionFactory; class InputSectionBase; @@ -47,13 +47,13 @@ struct Expr { // If expression is section-relative the function below is used // to get the output section pointer. - std::function<const OutputSectionBase *()> Section; + std::function<const OutputSection *()> Section; uint64_t operator()(uint64_t Dot) const { return Val(Dot); } operator bool() const { return (bool)Val; } Expr(std::function<uint64_t(uint64_t)> Val, std::function<bool()> IsAbsolute, - std::function<const OutputSectionBase *()> Section) + std::function<const OutputSection *()> Section) : Val(Val), IsAbsolute(IsAbsolute), Section(Section) {} template <typename T> Expr(T V) : Expr(V, [] { return true; }, [] { return nullptr; }) {} @@ -213,9 +213,9 @@ public: virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0; virtual bool isDefined(StringRef S) = 0; virtual bool isAbsolute(StringRef S) = 0; - virtual const OutputSectionBase *getSymbolSection(StringRef S) = 0; - virtual const OutputSectionBase *getOutputSection(const Twine &Loc, - StringRef S) = 0; + virtual const OutputSection *getSymbolSection(StringRef S) = 0; + virtual const OutputSection *getOutputSection(const Twine &Loc, + StringRef S) = 0; virtual uint64_t getOutputSectionSize(StringRef S) = 0; }; @@ -268,12 +268,11 @@ public: uint64_t getSymbolValue(const Twine &Loc, StringRef S) override; bool isDefined(StringRef S) override; bool isAbsolute(StringRef S) override; - const OutputSectionBase *getSymbolSection(StringRef S) override; - const OutputSectionBase *getOutputSection(const Twine &Loc, - StringRef S) override; + const OutputSection *getSymbolSection(StringRef S) override; + const OutputSection *getOutputSection(const Twine &Loc, StringRef S) override; uint64_t getOutputSectionSize(StringRef S) override; - std::vector<OutputSectionBase *> *OutputSections; + std::vector<OutputSection *> *OutputSections; int getSectionIndex(StringRef Name); @@ -294,19 +293,18 @@ private: std::vector<size_t> getPhdrIndices(StringRef SectionName); size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName); - MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd, - OutputSectionBase *Sec); + MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd, OutputSection *Sec); uintX_t Dot; std::function<uint64_t()> LMAOffset; - OutputSectionBase *CurOutSec = nullptr; + OutputSection *CurOutSec = nullptr; MemoryRegion *CurMemRegion = nullptr; uintX_t ThreadBssOffset = 0; - void switchTo(OutputSectionBase *Sec); + void switchTo(OutputSection *Sec); void flush(); void output(InputSection *Sec); void process(BaseCommand &Base); - llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS; + llvm::DenseSet<OutputSection *> AlreadyOutputOS; llvm::DenseSet<InputSectionBase *> AlreadyOutputIS; }; diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 9fb58d95cc8..576e3dc878b 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -95,26 +95,25 @@ static void writeInputSection(raw_fd_ostream &OS, const InputSection *IS, template <class ELFT> static void writeMapFile2(raw_fd_ostream &OS, - ArrayRef<OutputSectionBase *> OutputSections) { + ArrayRef<OutputSection *> OutputSections) { int Width = ELFT::Is64Bits ? 16 : 8; OS << left_justify("Address", Width) << ' ' << left_justify("Size", Width) << " Align Out In File Symbol\n"; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSection *Sec : OutputSections) { writeOutSecLine(OS, Width, Sec->Addr, Sec->Size, Sec->Addralign, Sec->Name); OS << '\n'; StringRef PrevName = ""; - Sec->forEachInputSection([&](InputSectionBase *S) { - if (const auto *IS = dyn_cast<InputSection>(S)) - writeInputSection<ELFT>(OS, IS, PrevName); - }); + for (InputSection *IS : Sec->Sections) { + writeInputSection<ELFT>(OS, IS, PrevName); + } } } template <class ELFT> -void elf::writeMapFile(ArrayRef<OutputSectionBase *> OutputSections) { +void elf::writeMapFile(ArrayRef<OutputSection *> OutputSections) { if (Config->MapFile.empty()) return; @@ -126,7 +125,7 @@ void elf::writeMapFile(ArrayRef<OutputSectionBase *> OutputSections) { writeMapFile2<ELFT>(OS, OutputSections); } -template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionBase *>); -template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionBase *>); -template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionBase *>); -template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionBase *>); +template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSection *>); +template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSection *>); +template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSection *>); +template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSection *>); diff --git a/lld/ELF/MapFile.h b/lld/ELF/MapFile.h index e8a6ea592f6..24d636890e5 100644 --- a/lld/ELF/MapFile.h +++ b/lld/ELF/MapFile.h @@ -15,7 +15,7 @@ namespace lld { namespace elf { template <class ELFT> -void writeMapFile(llvm::ArrayRef<OutputSectionBase *> OutputSections); +void writeMapFile(llvm::ArrayRef<OutputSection *> OutputSections); } } diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 7ce9361bff8..1832fc88d8d 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -30,15 +30,7 @@ using namespace llvm::ELF; using namespace lld; using namespace lld::elf; -OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type, - uint64_t Flags) - : Name(Name) { - this->Type = Type; - this->Flags = Flags; - this->Addralign = 1; -} - -uint32_t OutputSectionBase::getPhdrFlags() const { +uint32_t OutputSection::getPhdrFlags() const { uint32_t Ret = PF_R; if (Flags & SHF_WRITE) Ret |= PF_W; @@ -48,7 +40,7 @@ uint32_t OutputSectionBase::getPhdrFlags() const { } template <class ELFT> -void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) { +void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) { Shdr->sh_entsize = Entsize; Shdr->sh_addralign = Addralign; Shdr->sh_type = Type; @@ -78,10 +70,24 @@ template <class ELFT> static uint64_t getEntsize(uint32_t Type) { } } -template <class ELFT> -OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags) - : OutputSectionBase(Name, Type, Flags) { - this->Entsize = getEntsize<ELFT>(Type); +OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags) + : Name(Name), Addralign(1), Flags(Flags), Type(Type) { + switch (Config->EKind) { + case ELFNoneKind: + llvm_unreachable("unknown kind"); + case ELF32LEKind: + this->Entsize = getEntsize<ELF32LE>(Type); + break; + case ELF32BEKind: + this->Entsize = getEntsize<ELF32BE>(Type); + break; + case ELF64LEKind: + this->Entsize = getEntsize<ELF64LE>(Type); + break; + case ELF64BEKind: + this->Entsize = getEntsize<ELF64BE>(Type); + break; + } } template <typename ELFT> @@ -92,18 +98,18 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) { return false; auto *LA = cast<InputSection>(A->template getLinkOrderDep<ELFT>()); auto *LB = cast<InputSection>(B->template getLinkOrderDep<ELFT>()); - OutputSectionBase *AOut = LA->OutSec; - OutputSectionBase *BOut = LB->OutSec; + OutputSection *AOut = LA->OutSec; + OutputSection *BOut = LB->OutSec; if (AOut != BOut) return AOut->SectionIndex < BOut->SectionIndex; return LA->OutSecOff < LB->OutSecOff; } -template <class ELFT> void OutputSection<ELFT>::finalize() { +template <class ELFT> void OutputSection::finalize() { if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) { std::sort(Sections.begin(), Sections.end(), compareByFilePosition<ELFT>); Size = 0; - assignOffsets(); + assignOffsets<ELFT>(); // We must preserve the link order dependency of sections with the // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We @@ -128,8 +134,7 @@ template <class ELFT> void OutputSection<ELFT>::finalize() { this->Info = S->OutSec->SectionIndex; } -template <class ELFT> -void OutputSection<ELFT>::addSection(InputSectionBase *C) { +void OutputSection::addSection(InputSectionBase *C) { assert(C->Live); auto *S = cast<InputSection>(C); Sections.push_back(S); @@ -141,17 +146,10 @@ void OutputSection<ELFT>::addSection(InputSectionBase *C) { this->Entsize = S->Entsize; } -template <class ELFT> -void OutputSection<ELFT>::forEachInputSection( - std::function<void(InputSectionBase *)> F) { - for (InputSection *S : Sections) - F(S); -} - // This function is called after we sort input sections // and scan relocations to setup sections' offsets. -template <class ELFT> void OutputSection<ELFT>::assignOffsets() { - uintX_t Off = this->Size; +template <class ELFT> void OutputSection::assignOffsets() { + uint64_t Off = this->Size; for (InputSection *S : Sections) { Off = alignTo(Off, S->Alignment); S->OutSecOff = Off; @@ -160,8 +158,7 @@ template <class ELFT> void OutputSection<ELFT>::assignOffsets() { this->Size = Off; } -template <class ELFT> -void OutputSection<ELFT>::sort(std::function<int(InputSectionBase *S)> Order) { +void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) { typedef std::pair<unsigned, InputSection *> Pair; auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; }; @@ -180,7 +177,7 @@ void OutputSection<ELFT>::sort(std::function<int(InputSectionBase *S)> Order) { // because the compiler keeps the original initialization order in a // translation unit and we need to respect that. // For more detail, read the section of the GCC's manual about init_priority. -template <class ELFT> void OutputSection<ELFT>::sortInitFini() { +void OutputSection::sortInitFini() { // Sort sections by priority. sort([](InputSectionBase *S) { return getPriority(S->Name); }); } @@ -239,7 +236,7 @@ static bool compCtors(const InputSection *A, const InputSection *B) { // Sorts input sections by the special rules for .ctors and .dtors. // Unfortunately, the rules are different from the one for .{init,fini}_array. // Read the comment above. -template <class ELFT> void OutputSection<ELFT>::sortCtorsDtors() { +void OutputSection::sortCtorsDtors() { std::stable_sort(Sections.begin(), Sections.end(), compCtors); } @@ -254,7 +251,7 @@ void fill(uint8_t *Buf, size_t Size, uint32_t Filler) { memcpy(Buf + I, V, Size - I); } -template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) { +template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) { Loc = Buf; if (uint32_t Filler = Script<ELFT>::X->getFiller(this->Name)) fill(Buf, this->Size, Filler); @@ -331,7 +328,7 @@ static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) { template <class ELFT> OutputSectionFactory<ELFT>::OutputSectionFactory( - std::vector<OutputSectionBase *> &OutputSections) + std::vector<OutputSection *> &OutputSections) : OutputSections(OutputSections) {} static uint64_t getIncompatibleFlags(uint64_t Flags) { @@ -367,7 +364,7 @@ void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase *IS, SectionKey Key = createKey<ELFT>(IS, OutsecName); uintX_t Flags = getOutFlags<ELFT>(IS); - OutputSectionBase *&Sec = Map[Key]; + OutputSection *&Sec = Map[Key]; if (Sec) { if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) error("Section has flags incompatible with others with the same name " + @@ -386,7 +383,7 @@ void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase *IS, In<ELFT>::EhFrame->addSection(IS); return; } - Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags); + Sec = make<OutputSection>(Key.Name, Type, Flags); OutputSections.push_back(Sec); } @@ -416,15 +413,25 @@ bool DenseMapInfo<SectionKey>::isEqual(const SectionKey &LHS, namespace lld { namespace elf { -template void OutputSectionBase::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr); -template void OutputSectionBase::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr); -template void OutputSectionBase::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr); -template void OutputSectionBase::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr); - -template class OutputSection<ELF32LE>; -template class OutputSection<ELF32BE>; -template class OutputSection<ELF64LE>; -template class OutputSection<ELF64BE>; +template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr); +template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr); +template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr); +template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr); + +template void OutputSection::assignOffsets<ELF32LE>(); +template void OutputSection::assignOffsets<ELF32BE>(); +template void OutputSection::assignOffsets<ELF64LE>(); +template void OutputSection::assignOffsets<ELF64BE>(); + +template void OutputSection::finalize<ELF32LE>(); +template void OutputSection::finalize<ELF32BE>(); +template void OutputSection::finalize<ELF64LE>(); +template void OutputSection::finalize<ELF64BE>(); + +template void OutputSection::writeTo<ELF32LE>(uint8_t *Buf); +template void OutputSection::writeTo<ELF32BE>(uint8_t *Buf); +template void OutputSection::writeTo<ELF64LE>(uint8_t *Buf); +template void OutputSection::writeTo<ELF64BE>(uint8_t *Buf); template class OutputSectionFactory<ELF32LE>; template class OutputSectionFactory<ELF32BE>; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index d2f0c3b1175..a6a0c2ab199 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -27,34 +27,23 @@ template <class ELFT> class EhInputSection; class InputSection; class InputSectionBase; template <class ELFT> class MergeInputSection; -template <class ELFT> class OutputSection; +class OutputSection; template <class ELFT> class ObjectFile; template <class ELFT> class SharedFile; template <class ELFT> class SharedSymbol; template <class ELFT> class DefinedRegular; // This represents a section in an output file. -// Different sub classes represent different types of sections. Some contain -// input sections, others are created by the linker. +// It is composed of multiple InputSections. // The writer creates multiple OutputSections and assign them unique, // non-overlapping file offsets and VAs. -class OutputSectionBase { +class OutputSection final { public: - enum Kind { - Base, - Regular, - }; + OutputSection(StringRef Name, uint32_t Type, uint64_t Flags); - OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags); uint64_t getLMA() const { return Addr + LMAOffset; } template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); - virtual void addSection(InputSectionBase *C) {} - virtual Kind getKind() const { return Base; } - static bool classof(const OutputSectionBase *B) { - return B->getKind() == Base; - } - unsigned SectionIndex; uint32_t getPhdrFlags() const; @@ -74,13 +63,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; - - virtual void finalize() {} - virtual void forEachInputSection(std::function<void(InputSectionBase *)> F) {} - virtual void assignOffsets() {} - virtual void writeTo(uint8_t *Buf) {} - virtual ~OutputSectionBase() = default; + OutputSection *FirstInPtLoad = nullptr; StringRef Name; @@ -96,29 +79,14 @@ public: uint32_t Type = 0; uint32_t Info = 0; uint32_t Link = 0; -}; - -template <class ELFT> class OutputSection final : public OutputSectionBase { -public: - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::Rel Elf_Rel; - 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(InputSectionBase *C); void sort(std::function<int(InputSectionBase *S)> Order); void sortInitFini(); void sortCtorsDtors(); - void writeTo(uint8_t *Buf) override; - void finalize() override; - void forEachInputSection(std::function<void(InputSectionBase *)> F) override; - void assignOffsets() override; - Kind getKind() const override { return Regular; } - static bool classof(const OutputSectionBase *B) { - return B->getKind() == Regular; - } + template <class ELFT> void writeTo(uint8_t *Buf); + template <class ELFT> void finalize(); + template <class ELFT> void assignOffsets(); std::vector<InputSection *> Sections; // Location in the output buffer. @@ -133,17 +101,17 @@ template <class ELFT> struct Out { typedef typename ELFT::Phdr Elf_Phdr; static uint8_t First; - static OutputSection<ELFT> *Bss; - static OutputSection<ELFT> *BssRelRo; - static OutputSectionBase *Opd; + static OutputSection *Bss; + static OutputSection *BssRelRo; + static OutputSection *Opd; static uint8_t *OpdBuf; static PhdrEntry *TlsPhdr; - static OutputSectionBase *DebugInfo; - static OutputSectionBase *ElfHeader; - static OutputSectionBase *ProgramHeaders; - static OutputSectionBase *PreinitArray; - static OutputSectionBase *InitArray; - static OutputSectionBase *FiniArray; + static OutputSection *DebugInfo; + static OutputSection *ElfHeader; + static OutputSection *ProgramHeaders; + static OutputSection *PreinitArray; + static OutputSection *InitArray; + static OutputSection *FiniArray; }; struct SectionKey { @@ -174,13 +142,13 @@ template <class ELFT> class OutputSectionFactory { typedef typename ELFT::uint uintX_t; public: - OutputSectionFactory(std::vector<OutputSectionBase *> &OutputSections); + OutputSectionFactory(std::vector<OutputSection *> &OutputSections); ~OutputSectionFactory(); void addInputSec(InputSectionBase *IS, StringRef OutsecName); private: - llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map; - std::vector<OutputSectionBase *> &OutputSections; + llvm::SmallDenseMap<SectionKey, OutputSection *> Map; + std::vector<OutputSection *> &OutputSections; }; template <class ELFT> uint64_t getHeaderSize() { @@ -190,17 +158,17 @@ template <class ELFT> uint64_t getHeaderSize() { } template <class ELFT> uint8_t Out<ELFT>::First; -template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss; -template <class ELFT> OutputSection<ELFT> *Out<ELFT>::BssRelRo; -template <class ELFT> OutputSectionBase *Out<ELFT>::Opd; +template <class ELFT> OutputSection *Out<ELFT>::Bss; +template <class ELFT> OutputSection *Out<ELFT>::BssRelRo; +template <class ELFT> OutputSection *Out<ELFT>::Opd; template <class ELFT> uint8_t *Out<ELFT>::OpdBuf; template <class ELFT> PhdrEntry *Out<ELFT>::TlsPhdr; -template <class ELFT> OutputSectionBase *Out<ELFT>::DebugInfo; -template <class ELFT> OutputSectionBase *Out<ELFT>::ElfHeader; -template <class ELFT> OutputSectionBase *Out<ELFT>::ProgramHeaders; -template <class ELFT> OutputSectionBase *Out<ELFT>::PreinitArray; -template <class ELFT> OutputSectionBase *Out<ELFT>::InitArray; -template <class ELFT> OutputSectionBase *Out<ELFT>::FiniArray; +template <class ELFT> OutputSection *Out<ELFT>::DebugInfo; +template <class ELFT> OutputSection *Out<ELFT>::ElfHeader; +template <class ELFT> OutputSection *Out<ELFT>::ProgramHeaders; +template <class ELFT> OutputSection *Out<ELFT>::PreinitArray; +template <class ELFT> OutputSection *Out<ELFT>::InitArray; +template <class ELFT> OutputSection *Out<ELFT>::FiniArray; } // namespace elf } // namespace lld diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 74d6d96dcf8..35030888208 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -485,7 +485,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) { // See if this symbol is in a read-only segment. If so, preserve the symbol's // memory protection by reserving space in the .bss.rel.ro section. bool IsReadOnly = isReadOnly(SS); - OutputSection<ELFT> *OSec = IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss; + OutputSection *OSec = IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss; // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc. auto *ISec = @@ -866,7 +866,7 @@ template <class ELFT> void scanRelocations(InputSectionBase &S) { // offsets. // This may invalidate any output section offsets stored outside of InputSection template <class ELFT> -static void mergeThunks(OutputSection<ELFT> *OS, +static void mergeThunks(OutputSection *OS, std::vector<ThunkSection<ELFT> *> &Thunks) { // Order Thunks in ascending OutSecOff auto ThunkCmp = [](const ThunkSection<ELFT> *A, const ThunkSection<ELFT> *B) { @@ -893,7 +893,7 @@ static void mergeThunks(OutputSection<ELFT> *OS, Thunks.end(), std::back_inserter(Tmp), MergeCmp); OS->Sections = std::move(Tmp); OS->Size = 0; - OS->assignOffsets(); + OS->assignOffsets<ELFT>(); } // Process all relocations from the InputSections that have been assigned @@ -907,14 +907,13 @@ static void mergeThunks(OutputSection<ELFT> *OS, // FIXME: All Thunks are assumed to be in range of the relocation. Range // extension Thunks are not yet supported. template <class ELFT> -void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { +void createThunks(ArrayRef<OutputSection *> OutputSections) { // Track Symbols that already have a Thunk DenseMap<SymbolBody *, Thunk<ELFT> *> ThunkedSymbols; // Track InputSections that have a ThunkSection placed in front DenseMap<InputSection *, ThunkSection<ELFT> *> ThunkedSections; // Track the ThunksSections that need to be inserted into an OutputSection - std::map<OutputSection<ELFT> *, std::vector<ThunkSection<ELFT> *>> - ThunkSections; + std::map<OutputSection *, std::vector<ThunkSection<ELFT> *>> ThunkSections; // Find or create a Thunk for Body for relocation Type auto GetThunk = [&](SymbolBody &Body, uint32_t Type) { @@ -925,11 +924,11 @@ void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { }; // Find or create a ThunkSection to be placed immediately before IS - auto GetISThunkSec = [&](InputSection *IS, OutputSection<ELFT> *OS) { + auto GetISThunkSec = [&](InputSection *IS, OutputSection *OS) { ThunkSection<ELFT> *TS = ThunkedSections.lookup(IS); if (TS) return TS; - auto *TOS = cast<OutputSection<ELFT>>(IS->OutSec); + auto *TOS = cast<OutputSection>(IS->OutSec); TS = make<ThunkSection<ELFT>>(TOS, IS->OutSecOff); ThunkSections[OS].push_back(TS); ThunkedSections[IS] = TS; @@ -937,7 +936,7 @@ void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { }; // Find or create a ThunkSection to be placed as last executable section in // OS. - auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection<ELFT> *OS) { + auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection *OS) { if (TS == nullptr) { uint32_t Off = 0; for (auto *IS : OS->Sections) { @@ -956,8 +955,8 @@ void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { // We separate the creation of ThunkSections from the insertion of the // ThunkSections back into the OutputSection as ThunkSections are not always // inserted into the same OutputSection as the caller. - for (OutputSectionBase *Base : OutputSections) { - auto *OS = dyn_cast<OutputSection<ELFT>>(Base); + for (OutputSection *Base : OutputSections) { + auto *OS = dyn_cast<OutputSection>(Base); if (OS == nullptr) continue; @@ -997,9 +996,9 @@ template void scanRelocations<ELF32BE>(InputSectionBase &); template void scanRelocations<ELF64LE>(InputSectionBase &); template void scanRelocations<ELF64BE>(InputSectionBase &); -template void createThunks<ELF32LE>(ArrayRef<OutputSectionBase *>); -template void createThunks<ELF32BE>(ArrayRef<OutputSectionBase *>); -template void createThunks<ELF64LE>(ArrayRef<OutputSectionBase *>); -template void createThunks<ELF64BE>(ArrayRef<OutputSectionBase *>); +template void createThunks<ELF32LE>(ArrayRef<OutputSection *>); +template void createThunks<ELF32BE>(ArrayRef<OutputSection *>); +template void createThunks<ELF64LE>(ArrayRef<OutputSection *>); +template void createThunks<ELF64BE>(ArrayRef<OutputSection *>); } } diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index d1420cf37ac..e45d5fa61b4 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -17,7 +17,7 @@ namespace elf { class SymbolBody; class InputSection; class InputSectionBase; -class OutputSectionBase; +class OutputSection; // List of target-independent relocation types. Relocations read // from files are converted to these types so that the main code @@ -112,7 +112,7 @@ struct Relocation { template <class ELFT> void scanRelocations(InputSectionBase &); template <class ELFT> -void createThunks(ArrayRef<OutputSectionBase *> OutputSections); +void createThunks(ArrayRef<OutputSection *> OutputSections); // Return a int64_t to make sure we get the sign extension out of the way as // early as possible. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 47dd62e8ccf..405c44a0671 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -397,7 +397,7 @@ SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, template <typename ELFT> Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N, - const OutputSectionBase *Section, + const OutputSection *Section, uintX_t Value, uint8_t StOther) { Symbol *S; bool WasInserted; diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 2b8a7f982dc..c35f479a55d 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -19,7 +19,6 @@ namespace lld { namespace elf { class Lazy; -class OutputSectionBase; struct Symbol; // SymbolTable is a bucket of all known symbols, including defined, @@ -62,8 +61,8 @@ public: uintX_t Value, uintX_t Size, uint8_t Binding, InputSectionBase *Section, InputFile *File); - Symbol *addSynthetic(StringRef N, const OutputSectionBase *Section, - uintX_t Value, uint8_t StOther); + Symbol *addSynthetic(StringRef N, const OutputSection *Section, uintX_t Value, + uint8_t StOther); void addShared(SharedFile<ELFT> *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 bbfcb2ec69c..f0572d2e3ba 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -35,7 +35,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { switch (Body.kind()) { case SymbolBody::DefinedSyntheticKind: { auto &D = cast<DefinedSynthetic>(Body); - const OutputSectionBase *Sec = D.Section; + const OutputSection *Sec = D.Section; if (!Sec) return D.Value; if (D.Value == uintX_t(-1)) @@ -62,7 +62,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { Offset += Addend; Addend = 0; } - const OutputSectionBase *OutSec = IS->getOutputSection<ELFT>(); + const OutputSection *OutSec = IS->getOutputSection<ELFT>(); uintX_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset<ELFT>(Offset); if (D.isTls() && !Config->Relocatable) { if (!Out<ELFT>::TlsPhdr) diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index ab19aa43d17..4fc130b15c7 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -30,8 +30,7 @@ class BitcodeFile; class InputFile; class LazyObjectFile; template <class ELFT> class ObjectFile; -template <class ELFT> class OutputSection; -class OutputSectionBase; +class OutputSection; template <class ELFT> class SharedFile; struct Symbol; @@ -219,8 +218,7 @@ template <class ELFT> InputSectionBase *DefinedRegular<ELFT>::NullInputSection; // If Section is null, this symbol is relative to the image base. class DefinedSynthetic : public Defined { public: - DefinedSynthetic(StringRef Name, uint64_t Value, - const OutputSectionBase *Section) + DefinedSynthetic(StringRef Name, uint64_t Value, const OutputSection *Section) : Defined(SymbolBody::DefinedSyntheticKind, Name, /*IsLocal=*/false, llvm::ELF::STV_HIDDEN, 0 /* Type */), Value(Value), Section(Section) {} @@ -230,7 +228,7 @@ public: } uint64_t Value; - const OutputSectionBase *Section; + const OutputSection *Section; }; class Undefined : public SymbolBody { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index d3575a1fb29..8a881f8a41e 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -769,7 +769,7 @@ template <class ELFT> typename MipsGotSection<ELFT>::uintX_t MipsGotSection<ELFT>::getPageEntryOffset(const SymbolBody &B, int64_t Addend) const { - const OutputSectionBase *OutSec = + const OutputSection *OutSec = cast<DefinedRegular<ELFT>>(&B) ->Section->template getOutputSection<ELFT>(); uintX_t SecAddr = getMipsPageAddr(OutSec->Addr); @@ -827,7 +827,7 @@ unsigned MipsGotSection<ELFT>::getLocalEntriesNum() const { template <class ELFT> void MipsGotSection<ELFT>::finalize() { PageEntriesNum = 0; - for (std::pair<const OutputSectionBase *, size_t> &P : PageIndexMap) { + for (std::pair<const OutputSection *, size_t> &P : PageIndexMap) { // For each output section referenced by GOT page relocations calculate // and save into PageIndexMap an upper bound of MIPS GOT entries required // to store page addresses of local symbols. We assume the worst case - @@ -877,7 +877,7 @@ template <class ELFT> void MipsGotSection<ELFT>::writeTo(uint8_t *Buf) { P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31); Buf += HeaderEntriesNum * sizeof(uintX_t); // Write 'page address' entries to the local part of the GOT. - for (std::pair<const OutputSectionBase *, size_t> &L : PageIndexMap) { + for (std::pair<const OutputSection *, size_t> &L : PageIndexMap) { size_t PageCount = getMipsPageCount(L.first->Size); uintX_t FirstPageAddr = getMipsPageAddr(L.first->Addr); for (size_t PI = 0; PI < PageCount; ++PI) { @@ -1381,7 +1381,7 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) { ESym->st_shndx = SHN_ABS; ESym->st_value = Body.Value; } else { - const OutputSectionBase *OutSec = Section->getOutputSection<ELFT>(); + const OutputSection *OutSec = Section->getOutputSection<ELFT>(); ESym->st_shndx = OutSec->SectionIndex; ESym->st_value = OutSec->Addr + Section->getOffset(Body); } @@ -1412,7 +1412,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { ESym->setVisibility(Body->symbol()->Visibility); ESym->st_value = Body->getVA<ELFT>(); - if (const OutputSectionBase *OutSec = getOutputSection(Body)) { + if (const OutputSection *OutSec = getOutputSection(Body)) { ESym->st_shndx = OutSec->SectionIndex; } else if (isa<DefinedRegular<ELFT>>(Body)) { ESym->st_shndx = SHN_ABS; @@ -1439,7 +1439,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { } template <class ELFT> -const OutputSectionBase * +const OutputSection * SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) { switch (Sym->kind()) { case SymbolBody::DefinedSyntheticKind: @@ -2173,7 +2173,7 @@ ARMExidxSentinelSection<ELFT>::ARMExidxSentinelSection() template <class ELFT> void ARMExidxSentinelSection<ELFT>::writeTo(uint8_t *Buf) { // Get the InputSection before us, we are by definition last - auto RI = cast<OutputSection<ELFT>>(this->OutSec)->Sections.rbegin(); + auto RI = cast<OutputSection>(this->OutSec)->Sections.rbegin(); InputSection *LE = *(++RI); InputSection *LC = cast<InputSection>(LE->template getLinkOrderDep<ELFT>()); uint64_t S = LC->OutSec->Addr + @@ -2184,7 +2184,7 @@ void ARMExidxSentinelSection<ELFT>::writeTo(uint8_t *Buf) { } template <class ELFT> -ThunkSection<ELFT>::ThunkSection(OutputSectionBase *OS, uint64_t Off) +ThunkSection<ELFT>::ThunkSection(OutputSection *OS, uint64_t Off) : SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, sizeof(typename ELFT::uint), ".text.thunk") { this->OutSec = OS; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 98b6c8beeb1..34a922da772 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -249,7 +249,7 @@ private: uint32_t PageEntriesNum = 0; // Map output sections referenced by MIPS GOT relocations // to the first index of "Page" entries allocated for this section. - llvm::SmallMapVector<const OutputSectionBase *, size_t, 16> PageIndexMap; + llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap; typedef std::pair<const SymbolBody *, uintX_t> GotEntry; typedef std::vector<GotEntry> GotEntries; @@ -364,13 +364,13 @@ class DynamicSection final : public SyntheticSection<ELFT> { struct Entry { int32_t Tag; union { - OutputSectionBase *OutSec; + OutputSection *OutSec; InputSection *InSec; uint64_t Val; const SymbolBody *Sym; }; enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind; - Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr) + Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr) : Tag(Tag), OutSec(OutSec), Kind(Kind) {} Entry(int32_t Tag, InputSection *Sec) : Tag(Tag), InSec(Sec), Kind(InSecAddr) {} @@ -443,7 +443,7 @@ public: ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; } - static const OutputSectionBase *getOutputSection(SymbolBody *Sym); + static const OutputSection *getOutputSection(SymbolBody *Sym); private: void writeLocalSymbols(uint8_t *&Buf); @@ -777,7 +777,7 @@ public: template <class ELFT> class ThunkSection : public SyntheticSection<ELFT> { public: // ThunkSection in OS, with desired OutSecOff of Off - ThunkSection(OutputSectionBase *OS, uint64_t Off); + ThunkSection(OutputSection *OS, uint64_t Off); // Add a newly created Thunk to this container: // Thunk is given offset from start of this InputSection diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 3cace69e7fb..046b6a23d48 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -65,7 +65,7 @@ template <class ELFT> static std::string getErrorLoc(uint8_t *Loc) { if (!IS || !IS->OutSec) continue; - uint8_t *ISLoc = cast<OutputSection<ELFT>>(IS->OutSec)->Loc + IS->OutSecOff; + uint8_t *ISLoc = cast<OutputSection>(IS->OutSec)->Loc + IS->OutSecOff; if (ISLoc <= Loc && Loc < ISLoc + IS->template getSize<ELFT>()) return IS->template getLocation<ELFT>(Loc - ISLoc) + ": "; } diff --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h index 78b4bba8638..c0c410bbb25 100644 --- a/lld/ELF/Thunks.h +++ b/lld/ELF/Thunks.h @@ -16,7 +16,6 @@ namespace lld { namespace elf { class SymbolBody; template <class ELFT> class ThunkSection; -class OutputSectionBase; // Class to describe an instance of a Thunk. // A Thunk is a code-sequence inserted by the linker in between a caller and // the callee. The relocation to the callee is redirected to the Thunk, which diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1fc7e389826..397d86bc17d 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -77,14 +77,14 @@ private: std::unique_ptr<FileOutputBuffer> Buffer; - std::vector<OutputSectionBase *> OutputSections; + std::vector<OutputSection *> OutputSections; OutputSectionFactory<ELFT> Factory{OutputSections}; void addRelIpltSymbols(); void addStartEndSymbols(); - void addStartStopSymbols(OutputSectionBase *Sec); + void addStartStopSymbols(OutputSection *Sec); uintX_t getEntryAddr(); - OutputSectionBase *findSection(StringRef Name); + OutputSection *findSection(StringRef Name); std::vector<PhdrEntry> Phdrs; @@ -313,18 +313,18 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { // Create singleton output sections. Out<ELFT>::Bss = - make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - Out<ELFT>::BssRelRo = make<OutputSection<ELFT>>(".bss.rel.ro", SHT_NOBITS, - SHF_ALLOC | SHF_WRITE); + make<OutputSection>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + Out<ELFT>::BssRelRo = + make<OutputSection>(".bss.rel.ro", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true); In<ELFT>::Dynamic = make<DynamicSection<ELFT>>(); In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>( Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false); - Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC); + Out<ELFT>::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC); Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr); - Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC); + Out<ELFT>::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC); Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t)); if (needsInterpSection<ELFT>()) { @@ -529,13 +529,10 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { template <class ELFT> void Writer<ELFT>::addSectionSymbols() { // Create one STT_SECTION symbol for each output section we might // have a relocation with. - for (OutputSectionBase *Sec : OutputSections) { - InputSectionBase *First = nullptr; - Sec->forEachInputSection([&](InputSectionBase *D) { - if (!First) - First = D; - }); - auto *IS = dyn_cast_or_null<InputSection>(First); + for (OutputSection *Sec : OutputSections) { + InputSection *IS = nullptr; + if (!Sec->Sections.empty()) + IS = Sec->Sections[0]; if (!IS || isa<SyntheticSection<ELFT>>(IS) || IS->Type == SHT_REL || IS->Type == SHT_RELA) continue; @@ -565,7 +562,7 @@ static int getPPC64SectionRank(StringRef SectionName) { // All sections with SHF_MIPS_GPREL flag should be grouped together // because data in these sections is addressable with a gp relative address. -static int getMipsSectionRank(const OutputSectionBase *S) { +static int getMipsSectionRank(const OutputSection *S) { if ((S->Flags & SHF_MIPS_GPREL) == 0) return 0; if (S->Name == ".got") @@ -579,7 +576,7 @@ static int getMipsSectionRank(const OutputSectionBase *S) { // // This function returns true if a section needs to be put into a // PT_GNU_RELRO segment. -template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { +template <class ELFT> bool elf::isRelroSection(const OutputSection *Sec) { if (!Config->ZRelro) return false; @@ -609,8 +606,8 @@ template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { } template <class ELFT> -static bool compareSectionsNonScript(const OutputSectionBase *A, - const OutputSectionBase *B) { +static bool compareSectionsNonScript(const OutputSection *A, + const OutputSection *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->Name == ".interp"; @@ -707,8 +704,7 @@ static bool compareSectionsNonScript(const OutputSectionBase *A, // Output section ordering is determined by this function. template <class ELFT> -static bool compareSections(const OutputSectionBase *A, - const OutputSectionBase *B) { +static bool compareSections(const OutputSection *A, const OutputSection *B) { // For now, put sections mentioned in a linker script first. int AIndex = Script<ELFT>::X->getSectionIndex(A->Name); int BIndex = Script<ELFT>::X->getSectionIndex(B->Name); @@ -729,7 +725,7 @@ PhdrEntry::PhdrEntry(unsigned Type, unsigned Flags) { p_flags = Flags; } -void PhdrEntry::add(OutputSectionBase *Sec) { +void PhdrEntry::add(OutputSection *Sec) { Last = Sec; if (!First) First = Sec; @@ -740,7 +736,7 @@ void PhdrEntry::add(OutputSectionBase *Sec) { template <class ELFT> static DefinedSynthetic * -addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec, +addOptionalSynthetic(StringRef Name, OutputSection *Sec, typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) { if (SymbolBody *S = Symtab<ELFT>::X->find(Name)) if (!S->isInCurrentDSO()) @@ -862,20 +858,20 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // Sort input sections by section name suffixes for // __attribute__((init_priority(N))). -template <class ELFT> static void sortInitFini(OutputSectionBase *S) { +template <class ELFT> static void sortInitFini(OutputSection *S) { if (S) - reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini(); + reinterpret_cast<OutputSection *>(S)->sortInitFini(); } // Sort input sections by the special rule for .ctors and .dtors. -template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) { +template <class ELFT> static void sortCtorsDtors(OutputSection *S) { if (S) - reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors(); + reinterpret_cast<OutputSection *>(S)->sortCtorsDtors(); } // Sort input sections using the list provided by --symbol-ordering-file. template <class ELFT> -static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) { +static void sortBySymbolsOrder(ArrayRef<OutputSection *> OutputSections) { if (Config->SymbolOrderingFile.empty()) return; @@ -900,8 +896,8 @@ static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) { } // Sort sections by priority. - for (OutputSectionBase *Base : OutputSections) - if (auto *Sec = dyn_cast<OutputSection<ELFT>>(Base)) + for (OutputSection *Base : OutputSections) + if (auto *Sec = dyn_cast<OutputSection>(Base)) Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); }); } @@ -933,13 +929,12 @@ template <class ELFT> void Writer<ELFT>::createSections() { sortCtorsDtors<ELFT>(findSection(".ctors")); sortCtorsDtors<ELFT>(findSection(".dtors")); - for (OutputSectionBase *Sec : OutputSections) - Sec->assignOffsets(); + for (OutputSection *Sec : OutputSections) + Sec->assignOffsets<ELFT>(); } template <class ELFT> -static bool canSharePtLoad(const OutputSectionBase &S1, - const OutputSectionBase &S2) { +static bool canSharePtLoad(const OutputSection &S1, const OutputSection &S2) { if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC)) return false; @@ -995,12 +990,12 @@ template <class ELFT> void Writer<ELFT>::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, [](OutputSection *S) { return Script<ELFT>::X->getSectionIndex(S->Name) == INT_MAX; }); while (NonScriptI != E) { auto BestPos = std::max_element( - I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) { + I, NonScriptI, [&](OutputSection *&A, OutputSection *&B) { bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *A); bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *B); if (ACanSharePtLoad != BCanSharePtLoad) @@ -1036,7 +1031,7 @@ finalizeSynthetic(const std::vector<SyntheticSection<ELFT> *> &Sections) { if (SS && SS->OutSec && !SS->empty()) { SS->finalize(); SS->OutSec->Size = 0; - SS->OutSec->assignOffsets(); + SS->OutSec->template assignOffsets<ELFT>(); } } @@ -1045,7 +1040,7 @@ finalizeSynthetic(const std::vector<SyntheticSection<ELFT> *> &Sections) { // required to be in output. For example we don't need dynamic section content // sometimes. This function filters out such unused sections from output. template <class ELFT> -static void removeUnusedSyntheticSections(std::vector<OutputSectionBase *> &V) { +static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) { // All input synthetic sections that can be empty are placed after // all regular ones. We iterate over them all and exit at first // non-synthetic. @@ -1056,7 +1051,7 @@ static void removeUnusedSyntheticSections(std::vector<OutputSectionBase *> &V) { if (!SS->empty() || !SS->OutSec) continue; - OutputSection<ELFT> *OutSec = cast<OutputSection<ELFT>>(SS->OutSec); + OutputSection *OutSec = cast<OutputSection>(SS->OutSec); OutSec->Sections.erase( std::find(OutSec->Sections.begin(), OutSec->Sections.end(), SS)); // If there is no other sections in output section, remove it from output. @@ -1077,7 +1072,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { // addresses of each section by section name. Add such symbols. if (!Config->Relocatable) { addStartEndSymbols(); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) addStartStopSymbols(Sec); } @@ -1140,7 +1135,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { Out<ELFT>::ElfHeader->SectionIndex = 1; unsigned I = 1; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSection *Sec : OutputSections) { Sec->SectionIndex = I++; Sec->ShName = In<ELFT>::ShStrTab->addString(Sec->Name); } @@ -1164,8 +1159,8 @@ template <class ELFT> void Writer<ELFT>::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) - Sec->finalize(); + for (OutputSection *Sec : OutputSections) + Sec->finalize<ELFT>(); // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. @@ -1182,9 +1177,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { template <class ELFT> void Writer<ELFT>::addPredefinedSections() { // Add BSS sections. - auto Add = [=](OutputSection<ELFT> *Sec) { + auto Add = [=](OutputSection *Sec) { if (!Sec->Sections.empty()) { - Sec->assignOffsets(); + Sec->assignOffsets<ELFT>(); OutputSections.push_back(Sec); } }; @@ -1193,7 +1188,7 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { // ARM ABI requires .ARM.exidx to be terminated by some piece of data. // We have the terminater synthetic section class. Add that at the end. - auto *OS = dyn_cast_or_null<OutputSection<ELFT>>(findSection(".ARM.exidx")); + auto *OS = dyn_cast_or_null<OutputSection>(findSection(".ARM.exidx")); if (OS && !OS->Sections.empty() && !Config->Relocatable) OS->addSection(make<ARMExidxSentinelSection<ELFT>>()); } @@ -1201,7 +1196,7 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { // The linker is expected to define SECNAME_start and SECNAME_end // symbols for a few sections. This function defines them. template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { - auto Define = [&](StringRef Start, StringRef End, OutputSectionBase *OS) { + auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) { // These symbols resolve to the image base if the section does not exist. // A special value -1 indicates end of the section. addOptionalSynthetic<ELFT>(Start, OS, 0); @@ -1213,7 +1208,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { Define("__init_array_start", "__init_array_end", Out<ELFT>::InitArray); Define("__fini_array_start", "__fini_array_end", Out<ELFT>::FiniArray); - if (OutputSectionBase *Sec = findSection(".ARM.exidx")) + if (OutputSection *Sec = findSection(".ARM.exidx")) Define("__exidx_start", "__exidx_end", Sec); } @@ -1223,7 +1218,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { // respectively. This is not requested by the ELF standard, but GNU ld and // gold provide the feature, and used by many programs. template <class ELFT> -void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) { +void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) { StringRef S = Sec->Name; if (!isValidCIdentifier(S)) return; @@ -1231,15 +1226,14 @@ void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) { addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT); } -template <class ELFT> -OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) { - for (OutputSectionBase *Sec : OutputSections) +template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef Name) { + for (OutputSection *Sec : OutputSections) if (Sec->Name == Name) return Sec; return nullptr; } -template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) { +template <class ELFT> static bool needsPtLoad(OutputSection *Sec) { if (!(Sec->Flags & SHF_ALLOC)) return false; @@ -1277,13 +1271,13 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { AddHdr(PT_PHDR, PF_R)->add(Out<ELFT>::ProgramHeaders); // PT_INTERP must be the second entry if exists. - if (OutputSectionBase *Sec = findSection(".interp")) + if (OutputSection *Sec = findSection(".interp")) AddHdr(PT_INTERP, Sec->getPhdrFlags())->add(Sec); // Add the first PT_LOAD segment for regular output sections. uintX_t Flags = computeFlags<ELFT>(PF_R); PhdrEntry *Load = AddHdr(PT_LOAD, Flags); - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSection *Sec : OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; if (!needsPtLoad<ELFT>(Sec)) @@ -1305,7 +1299,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { // Add a TLS segment if any. PhdrEntry TlsHdr(PT_TLS, PF_R); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (Sec->Flags & SHF_TLS) TlsHdr.add(Sec); if (TlsHdr.First) @@ -1319,7 +1313,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { // PT_GNU_RELRO includes all sections that should be marked as // read-only by dynamic linker after proccessing relocations. PhdrEntry RelRo(PT_GNU_RELRO, PF_R); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (needsPtLoad<ELFT>(Sec) && isRelroSection<ELFT>(Sec)) RelRo.add(Sec); if (RelRo.First) @@ -1333,7 +1327,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::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 (OutputSection *Sec = findSection(".openbsd.randomdata")) AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags())->add(Sec); // PT_GNU_STACK is a special section to tell the loader to make the @@ -1356,7 +1350,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { // Create one PT_NOTE per a group of contiguous .note sections. PhdrEntry *Note = nullptr; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSection *Sec : OutputSections) { if (Sec->Type == SHT_NOTE) { if (!Note || Script<ELFT>::X->hasLMA(Sec->Name)) Note = AddHdr(PT_NOTE, PF_R); @@ -1374,7 +1368,7 @@ void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry> &Phdrs) { return; auto I = std::find_if( OutputSections.begin(), OutputSections.end(), - [](OutputSectionBase *Sec) { return Sec->Type == SHT_ARM_EXIDX; }); + [](OutputSection *Sec) { return Sec->Type == SHT_ARM_EXIDX; }); if (I == OutputSections.end()) return; @@ -1403,7 +1397,7 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() { auto I = std::find(OutputSections.begin(), End, P.Last); if (I == End || (I + 1) == End) continue; - OutputSectionBase *Sec = *(I + 1); + OutputSection *Sec = *(I + 1); if (needsPtLoad<ELFT>(Sec)) Sec->PageAlign = true; } @@ -1411,7 +1405,7 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() { template <class ELFT> bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs, - ArrayRef<OutputSectionBase *> OutputSections, + ArrayRef<OutputSection *> OutputSections, uint64_t Min) { auto FirstPTLoad = std::find_if(Phdrs.begin(), Phdrs.end(), @@ -1440,7 +1434,7 @@ bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs, return true; if (FirstPTLoad->First) - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (Sec->FirstInPtLoad == FirstPTLoad->First) Sec->FirstInPtLoad = Out<ELFT>::ElfHeader; FirstPTLoad->First = Out<ELFT>::ElfHeader; @@ -1474,7 +1468,7 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() { if (AllocateHeader) VA += getHeaderSize<ELFT>(); uintX_t ThreadBssOffset = 0; - for (OutputSectionBase *Sec : OutputSections) { + for (OutputSection *Sec : OutputSections) { uintX_t Alignment = Sec->Addralign; if (Sec->PageAlign) Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize); @@ -1502,8 +1496,8 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() { // virtual address (modulo the page size) so that the loader can load // executables without any address adjustment. template <class ELFT, class uintX_t> -static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) { - OutputSectionBase *First = Sec->FirstInPtLoad; +static uintX_t getFileAlignment(uintX_t Off, OutputSection *Sec) { + OutputSection *First = Sec->FirstInPtLoad; // If the section is not in a PT_LOAD, we just have to align it. if (!First) return alignTo(Off, Sec->Addralign); @@ -1519,7 +1513,7 @@ static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) { } template <class ELFT, class uintX_t> -static uintX_t setOffset(OutputSectionBase *Sec, uintX_t Off) { +static uintX_t setOffset(OutputSection *Sec, uintX_t Off) { if (Sec->Type == SHT_NOBITS) { Sec->Offset = Off; return Off; @@ -1532,7 +1526,7 @@ static uintX_t setOffset(OutputSectionBase *Sec, uintX_t Off) { template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() { uintX_t Off = 0; - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (Sec->Flags & SHF_ALLOC) Off = setOffset<ELFT>(Sec, Off); FileSize = alignTo(Off, sizeof(uintX_t)); @@ -1544,7 +1538,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { Off = setOffset<ELFT>(Out<ELFT>::ElfHeader, Off); Off = setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) Off = setOffset<ELFT>(Sec, Off); SectionHeaderOff = alignTo(Off, sizeof(uintX_t)); @@ -1555,8 +1549,8 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { // file offsets and VAs to all sections. template <class ELFT> void Writer<ELFT>::setPhdrs() { for (PhdrEntry &P : Phdrs) { - OutputSectionBase *First = P.First; - OutputSectionBase *Last = P.Last; + OutputSection *First = P.First; + OutputSection *Last = P.Last; if (First) { P.p_filesz = Last->Offset - First->Offset; if (Last->Type != SHT_NOBITS) @@ -1604,7 +1598,7 @@ template <class ELFT> typename ELFT::uint Writer<ELFT>::getEntryAddr() { return Addr; // Case 4 - if (OutputSectionBase *Sec = findSection(".text")) { + if (OutputSection *Sec = findSection(".text")) { if (Config->WarnMissingEntry) warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" + utohexstr(Sec->Addr)); @@ -1636,8 +1630,8 @@ static uint16_t getELFType() { // to each section. This function fixes some predefined // symbol values that depend on section address and size. template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() { - auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2, - OutputSectionBase *Sec, uint64_t Value) { + auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2, OutputSection *Sec, + uint64_t Value) { if (S1) { S1->Section = Sec; S1->Value = Value; @@ -1679,7 +1673,7 @@ template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() { // Find GP-relative section with the lowest address // and use this address to calculate default _gp value. uintX_t Gp = -1; - for (const OutputSectionBase * OS : OutputSections) + for (const OutputSection *OS : OutputSections) if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp) Gp = OS->Addr; if (Gp != (uintX_t)-1) @@ -1742,7 +1736,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { // Write the section header table. Note that the first table entry is null. auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) Sec->writeHeaderTo<ELFT>(++SHdrs); } @@ -1796,9 +1790,9 @@ template <class ELFT> void Writer<ELFT>::openFile() { template <class ELFT> void Writer<ELFT>::writeSectionsBinary() { uint8_t *Buf = Buffer->getBufferStart(); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (Sec->Flags & SHF_ALLOC) - Sec->writeTo(Buf + Sec->Offset); + Sec->writeTo<ELFT>(Buf + Sec->Offset); } // Write section contents to a mmap'ed file. @@ -1810,28 +1804,28 @@ template <class ELFT> void Writer<ELFT>::writeSections() { Out<ELFT>::Opd = findSection(".opd"); if (Out<ELFT>::Opd) { Out<ELFT>::OpdBuf = Buf + Out<ELFT>::Opd->Offset; - Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset); + Out<ELFT>::Opd->template writeTo<ELFT>(Buf + Out<ELFT>::Opd->Offset); } - OutputSectionBase *EhFrameHdr = + OutputSection *EhFrameHdr = In<ELFT>::EhFrameHdr ? In<ELFT>::EhFrameHdr->OutSec : nullptr; // In -r or -emit-relocs mode, write the relocation sections first as in // ELf_Rel targets we might find out that we need to modify the relocated // section while doing it. - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA) - Sec->writeTo(Buf + Sec->Offset); + Sec->writeTo<ELFT>(Buf + Sec->Offset); - for (OutputSectionBase *Sec : OutputSections) + for (OutputSection *Sec : OutputSections) if (Sec != Out<ELFT>::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL && Sec->Type != SHT_RELA) - Sec->writeTo(Buf + Sec->Offset); + Sec->writeTo<ELFT>(Buf + Sec->Offset); // The .eh_frame_hdr depends on .eh_frame section contents, therefore // it should be written after .eh_frame is written. if (EhFrameHdr) - EhFrameHdr->writeTo(Buf + EhFrameHdr->Offset); + EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset); } template <class ELFT> void Writer<ELFT>::writeBuildId() { @@ -1850,19 +1844,19 @@ template void elf::writeResult<ELF64LE>(); template void elf::writeResult<ELF64BE>(); template bool elf::allocateHeaders<ELF32LE>(std::vector<PhdrEntry> &, - ArrayRef<OutputSectionBase *>, + ArrayRef<OutputSection *>, uint64_t); template bool elf::allocateHeaders<ELF32BE>(std::vector<PhdrEntry> &, - ArrayRef<OutputSectionBase *>, + ArrayRef<OutputSection *>, uint64_t); template bool elf::allocateHeaders<ELF64LE>(std::vector<PhdrEntry> &, - ArrayRef<OutputSectionBase *>, + ArrayRef<OutputSection *>, uint64_t); template bool elf::allocateHeaders<ELF64BE>(std::vector<PhdrEntry> &, - ArrayRef<OutputSectionBase *>, + ArrayRef<OutputSection *>, uint64_t); -template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *); -template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *); -template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase *); -template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase *); +template bool elf::isRelroSection<ELF32LE>(const OutputSection *); +template bool elf::isRelroSection<ELF32BE>(const OutputSection *); +template bool elf::isRelroSection<ELF64LE>(const OutputSection *); +template bool elf::isRelroSection<ELF64BE>(const OutputSection *); diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h index 93ea264d7c1..c1cf149a070 100644 --- a/lld/ELF/Writer.h +++ b/lld/ELF/Writer.h @@ -18,20 +18,20 @@ namespace lld { namespace elf { class InputFile; -class OutputSectionBase; +class OutputSection; class InputSectionBase; template <class ELFT> class ObjectFile; template <class ELFT> class SymbolTable; template <class ELFT> void writeResult(); template <class ELFT> void markLive(); -template <class ELFT> bool isRelroSection(const OutputSectionBase *Sec); +template <class ELFT> bool isRelroSection(const OutputSection *Sec); // This describes a program header entry. // Each contains type, access flags and range of output sections that will be // placed in it. struct PhdrEntry { PhdrEntry(unsigned Type, unsigned Flags); - void add(OutputSectionBase *Sec); + void add(OutputSection *Sec); uint64_t p_paddr = 0; uint64_t p_vaddr = 0; @@ -42,16 +42,16 @@ struct PhdrEntry { uint32_t p_type = 0; uint32_t p_flags = 0; - OutputSectionBase *First = nullptr; - OutputSectionBase *Last = nullptr; + OutputSection *First = nullptr; + OutputSection *Last = nullptr; bool HasLMA = false; }; llvm::StringRef getOutputSectionName(llvm::StringRef Name); template <class ELFT> -bool allocateHeaders(std::vector<PhdrEntry> &, - llvm::ArrayRef<OutputSectionBase *>, uint64_t Min); +bool allocateHeaders(std::vector<PhdrEntry> &, llvm::ArrayRef<OutputSection *>, + uint64_t Min); template <class ELFT> uint32_t getMipsEFlags(); |