summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r--lld/ELF/Writer.cpp180
1 files changed, 87 insertions, 93 deletions
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 *);
OpenPOWER on IntegriCloud