summaryrefslogtreecommitdiff
path: root/ELF/SyntheticSections.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/SyntheticSections.cpp')
-rw-r--r--ELF/SyntheticSections.cpp97
1 files changed, 52 insertions, 45 deletions
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index d3db32613a8a..223fc9a0fd07 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -48,8 +48,8 @@ using namespace lld;
using namespace lld::elf;
uint64_t SyntheticSection::getVA() const {
- if (this->OutSec)
- return this->OutSec->Addr + this->OutSecOff;
+ if (OutputSection *Sec = getParent())
+ return Sec->Addr + OutSecOff;
return 0;
}
@@ -367,8 +367,8 @@ BssSection::BssSection(StringRef Name)
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name) {}
size_t BssSection::reserveSpace(uint64_t Size, uint32_t Alignment) {
- if (OutSec)
- OutSec->updateAlignment(Alignment);
+ if (OutputSection *Sec = getParent())
+ Sec->updateAlignment(Alignment);
this->Size = alignTo(this->Size, Alignment) + Size;
this->Alignment = std::max(this->Alignment, Alignment);
return this->Size - Size;
@@ -494,7 +494,7 @@ void EhFrameSection<ELFT>::addSectionAux(EhInputSection *Sec,
template <class ELFT>
void EhFrameSection<ELFT>::addSection(InputSectionBase *C) {
auto *Sec = cast<EhInputSection>(C);
- Sec->EHSec = this;
+ Sec->Parent = this;
updateAlignment(Sec->Alignment);
Sections.push_back(Sec);
for (auto *DS : Sec->DependentSections)
@@ -579,7 +579,7 @@ uint64_t EhFrameSection<ELFT>::getFdePc(uint8_t *Buf, size_t FdeOff,
if ((Enc & 0x70) == DW_EH_PE_absptr)
return Addr;
if ((Enc & 0x70) == DW_EH_PE_pcrel)
- return Addr + this->OutSec->Addr + Off;
+ return Addr + getParent()->Addr + Off;
fatal("unknown FDE size relative encoding");
}
@@ -610,7 +610,7 @@ template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) {
uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece);
for (SectionPiece *Fde : Cie->FdePieces) {
uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
- uint64_t FdeVA = this->OutSec->Addr + Fde->OutputOff;
+ uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
In<ELFT>::EhFrameHdr->addFde(Pc, FdeVA);
}
}
@@ -698,8 +698,7 @@ void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) {
// sections referenced by GOT relocations. Then later in the `finalize`
// method calculate number of "pages" required to cover all saved output
// section and allocate appropriate number of GOT entries.
- auto *DefSym = cast<DefinedRegular>(&Sym);
- PageIndexMap.insert({DefSym->Section->getOutputSection(), 0});
+ PageIndexMap.insert({Sym.getOutputSection(), 0});
return;
}
if (Sym.isTls()) {
@@ -766,8 +765,7 @@ static uint64_t getMipsPageCount(uint64_t Size) {
uint64_t MipsGotSection::getPageEntryOffset(const SymbolBody &B,
int64_t Addend) const {
- const OutputSection *OutSec =
- cast<DefinedRegular>(&B)->Section->getOutputSection();
+ const OutputSection *OutSec = B.getOutputSection();
uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
uint64_t SymAddr = getMipsPageAddr(B.getVA(Addend));
uint64_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff;
@@ -1071,11 +1069,11 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
if (this->Size)
return; // Already finalized.
- this->Link = InX::DynStrTab->OutSec->SectionIndex;
- if (In<ELFT>::RelaDyn->OutSec->Size > 0) {
+ this->Link = InX::DynStrTab->getParent()->SectionIndex;
+ if (In<ELFT>::RelaDyn->getParent()->Size > 0) {
bool IsRela = Config->IsRela;
add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn});
- add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->OutSec->Size});
+ add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getParent()->Size});
add({IsRela ? DT_RELAENT : DT_RELENT,
uint64_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
@@ -1088,9 +1086,9 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
}
}
- if (In<ELFT>::RelaPlt->OutSec->Size > 0) {
+ if (In<ELFT>::RelaPlt->getParent()->Size > 0) {
add({DT_JMPREL, In<ELFT>::RelaPlt});
- add({DT_PLTRELSZ, In<ELFT>::RelaPlt->OutSec->Size});
+ add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent()->Size});
add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
InX::GotPlt});
add({DT_PLTREL, uint64_t(Config->IsRela ? DT_RELA : DT_REL)});
@@ -1152,7 +1150,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
add({DT_MIPS_RLD_MAP, InX::MipsRldMap});
}
- this->OutSec->Link = this->Link;
+ getParent()->Link = this->Link;
// +1 for DT_NULL
this->Size = (Entries.size() + 1) * this->Entsize;
@@ -1168,7 +1166,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
P->d_un.d_ptr = E.OutSec->Addr;
break;
case Entry::InSecAddr:
- P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
+ P->d_un.d_ptr = E.InSec->getParent()->Addr + E.InSec->OutSecOff;
break;
case Entry::SecSize:
P->d_un.d_val = E.OutSec->Size;
@@ -1185,7 +1183,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
}
uint64_t DynamicReloc::getOffset() const {
- return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec);
+ return InputSec->getOutputSection()->Addr + InputSec->getOffset(OffsetInSec);
}
int64_t DynamicReloc::getAddend() const {
@@ -1258,11 +1256,11 @@ template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
}
template <class ELFT> void RelocationSection<ELFT>::finalizeContents() {
- this->Link = InX::DynSymTab ? InX::DynSymTab->OutSec->SectionIndex
- : InX::SymTab->OutSec->SectionIndex;
+ this->Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex
+ : InX::SymTab->getParent()->SectionIndex;
// Set required output section properties.
- this->OutSec->Link = this->Link;
+ getParent()->Link = this->Link;
}
SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
@@ -1293,14 +1291,14 @@ static bool sortMipsSymbols(const SymbolTableEntry &L,
// function. (For .dynsym, we don't do that because symbols for
// dynamic linking are inherently all globals.)
void SymbolTableBaseSection::finalizeContents() {
- this->OutSec->Link = StrTabSec.OutSec->SectionIndex;
+ getParent()->Link = StrTabSec.getParent()->SectionIndex;
// If it is a .dynsym, there should be no local symbols, but we need
// to do a few things for the dynamic linker.
if (this->Type == SHT_DYNSYM) {
// Section's Info field has the index of the first non-local symbol.
// Because the first symbol entry is a null entry, 1 is the first.
- this->OutSec->Info = 1;
+ getParent()->Info = 1;
if (InX::GnuHashTab) {
// NB: It also sorts Symbols to meet the GNU hash table requirements.
@@ -1326,7 +1324,7 @@ void SymbolTableBaseSection::postThunkContents() {
S.Symbol->symbol()->computeBinding() == STB_LOCAL;
});
size_t NumLocals = It - Symbols.begin();
- this->OutSec->Info = NumLocals + 1;
+ getParent()->Info = NumLocals + 1;
}
void SymbolTableBaseSection::addSymbol(SymbolBody *B) {
@@ -1344,8 +1342,7 @@ size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) {
// This is used for -r, so we have to handle multiple section
// symbols being combined.
if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
- return cast<DefinedRegular>(Body)->Section->getOutputSection() ==
- cast<DefinedRegular>(E.Symbol)->Section->getOutputSection();
+ return Body->getOutputSection() == E.Symbol->getOutputSection();
return false;
});
if (I == Symbols.end())
@@ -1456,7 +1453,7 @@ GnuHashTableSection::GnuHashTableSection()
}
void GnuHashTableSection::finalizeContents() {
- this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
// Computes bloom filter size in word size. We want to allocate 8
// bits for each symbol. It must be a power of two.
@@ -1590,7 +1587,7 @@ HashTableSection<ELFT>::HashTableSection()
}
template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
- this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
unsigned NumEntries = 2; // nbucket and nchain.
NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.
@@ -1801,7 +1798,7 @@ void GdbIndexSection::finalizeContents() {
for (InputSectionBase *S : InputSections)
if (InputSection *IS = dyn_cast<InputSection>(S))
- if (IS->OutSec && IS->Name == ".debug_info")
+ if (IS->getParent() && IS->Name == ".debug_info")
readDwarf(IS);
SymbolTable.finalizeContents();
@@ -1846,7 +1843,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
// Write the address area.
for (AddressEntry &E : AddressArea) {
- uint64_t BaseAddr = E.Section->OutSec->Addr + E.Section->getOffset(0);
+ uint64_t BaseAddr = E.Section->getParent()->Addr + E.Section->getOffset(0);
write64le(Buf, BaseAddr + E.LowAddress);
write64le(Buf + 8, BaseAddr + E.HighAddress);
write32le(Buf + 16, E.CuIndex);
@@ -1906,7 +1903,7 @@ template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
Buf[2] = DW_EH_PE_udata4;
Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
- write32<E>(Buf + 4, In<ELFT>::EhFrame->OutSec->Addr - this->getVA() - 4);
+ write32<E>(Buf + 4, In<ELFT>::EhFrame->getParent()->Addr - this->getVA() - 4);
write32<E>(Buf + 8, Fdes.size());
Buf += 12;
@@ -1948,12 +1945,12 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
for (VersionDefinition &V : Config->VersionDefinitions)
V.NameOff = InX::DynStrTab->addString(V.Name);
- this->OutSec->Link = InX::DynStrTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
// sh_info should be set to the number of definitions. This fact is missed in
// documentation, but confirmed by binutils community:
// https://sourceware.org/ml/binutils/2014-11/msg00355.html
- this->OutSec->Info = getVerDefNum();
+ getParent()->Info = getVerDefNum();
}
template <class ELFT>
@@ -2001,7 +1998,7 @@ VersionTableSection<ELFT>::VersionTableSection()
template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
// At the moment of june 2016 GNU docs does not mention that sh_link field
// should be set, but Sun docs do. Also readelf relies on this field.
- this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
}
template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
@@ -2093,8 +2090,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
}
template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
- this->OutSec->Link = InX::DynStrTab->OutSec->SectionIndex;
- this->OutSec->Info = Needed.size();
+ getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
+ getParent()->Info = Needed.size();
}
template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
@@ -2115,7 +2112,7 @@ MergeSyntheticSection::MergeSyntheticSection(StringRef Name, uint32_t Type,
void MergeSyntheticSection::addSection(MergeInputSection *MS) {
assert(!Finalized);
- MS->MergeSec = this;
+ MS->Parent = this;
Sections.push_back(MS);
}
@@ -2186,13 +2183,23 @@ ARMExidxSentinelSection::ARMExidxSentinelSection()
// This section will have been sorted last in the .ARM.exidx table.
// This table entry will have the form:
// | PREL31 upper bound of code that has exception tables | EXIDX_CANTUNWIND |
+// The sentinel must have the PREL31 value of an address higher than any
+// address described by any other table entry.
void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
- // Get the InputSection before us, we are by definition last
- auto RI = this->OutSec->Sections.rbegin();
- InputSection *LE = *(++RI);
- InputSection *LC = cast<InputSection>(LE->getLinkOrderDep());
- uint64_t S = LC->OutSec->Addr + LC->getOffset(LC->getSize());
- uint64_t P = this->getVA();
+ // The Sections are sorted in order of ascending PREL31 address with the
+ // sentinel last. We need to find the InputSection that precedes the
+ // sentinel. By construction the Sentinel is in the last
+ // InputSectionDescription as the InputSection that precedes it.
+ OutputSectionCommand *C = Script->getCmd(getParent());
+ auto ISD = std::find_if(C->Commands.rbegin(), C->Commands.rend(),
+ [](const BaseCommand *Base) {
+ return isa<InputSectionDescription>(Base);
+ });
+ auto L = cast<InputSectionDescription>(*ISD);
+ InputSection *Highest = L->Sections[L->Sections.size() - 2];
+ InputSection *LS = Highest->getLinkOrderDep();
+ uint64_t S = LS->getParent()->Addr + LS->getOffset(LS->getSize());
+ uint64_t P = getVA();
Target->relocateOne(Buf, R_ARM_PREL31, S - P);
write32le(Buf + 4, 0x1);
}
@@ -2200,7 +2207,7 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
Config->Wordsize, ".text.thunk") {
- this->OutSec = OS;
+ this->Parent = OS;
this->OutSecOff = Off;
}