summaryrefslogtreecommitdiffstats
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-05-31 20:17:44 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-05-31 20:17:44 +0000
commitdb5e56f7b2c8fd96321bed5b829e77b6e699bfdf (patch)
tree4caf5d172b7bd90a4842c904d9936f942c1e82e3 /lld/ELF/InputSection.cpp
parent1d4cde62832ac8cd8d4955a864bc794523f932d9 (diff)
downloadbcm5719-llvm-db5e56f7b2c8fd96321bed5b829e77b6e699bfdf.tar.gz
bcm5719-llvm-db5e56f7b2c8fd96321bed5b829e77b6e699bfdf.zip
Store a single Parent pointer for InputSectionBase.
Before InputSectionBase had an OutputSection pointer, but that was not always valid. For example, if it was a merge section one actually had to look at MergeSec->OutSec. This was brittle and caused bugs like the one fixed by r304260. We now have a single Parent pointer that points to an OutputSection for InputSection, but to a SyntheticSection for merge sections and .eh_frame. This makes it impossible to accidentally access an invalid OutSec. llvm-svn: 304338
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 979369b26db..4af05c1a187 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -139,21 +139,24 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const {
return Offset;
case Merge:
const MergeInputSection *MS = cast<MergeInputSection>(this);
- if (MS->MergeSec)
- return MS->MergeSec->OutSecOff + MS->getOffset(Offset);
+ if (InputSection *IS = MS->getParent())
+ return IS->OutSecOff + MS->getOffset(Offset);
return MS->getOffset(Offset);
}
llvm_unreachable("invalid section kind");
}
OutputSection *SectionBase::getOutputSection() {
+ InputSection *Sec;
if (auto *IS = dyn_cast<InputSection>(this))
- return IS->OutSec;
- if (auto *MS = dyn_cast<MergeInputSection>(this))
- return MS->MergeSec ? MS->MergeSec->OutSec : nullptr;
- if (auto *EH = dyn_cast<EhInputSection>(this))
- return EH->EHSec->OutSec;
- return cast<OutputSection>(this);
+ Sec = IS;
+ else if (auto *MS = dyn_cast<MergeInputSection>(this))
+ Sec = MS->getParent();
+ else if (auto *EH = dyn_cast<EhInputSection>(this))
+ Sec = EH->getParent();
+ else
+ return cast<OutputSection>(this);
+ return Sec ? Sec->getParent() : nullptr;
}
// Uncompress section contents. Note that this function is called
@@ -301,6 +304,10 @@ bool InputSectionBase::classof(const SectionBase *S) {
return S->kind() != Output;
}
+OutputSection *InputSection::getParent() const {
+ return cast_or_null<OutputSection>(Parent);
+}
+
void InputSection::copyShtGroup(uint8_t *Buf) {
assert(this->Type == SHT_GROUP);
@@ -315,7 +322,8 @@ void InputSection::copyShtGroup(uint8_t *Buf) {
ArrayRef<InputSectionBase *> Sections = this->File->getSections();
for (uint32_t Val : From.slice(1)) {
uint32_t Index = read32(&Val, Config->Endianness);
- write32(To++, Sections[Index]->OutSec->SectionIndex, Config->Endianness);
+ write32(To++, Sections[Index]->getOutputSection()->SectionIndex,
+ Config->Endianness);
}
}
@@ -348,7 +356,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// Output section VA is zero for -r, so r_offset is an offset within the
// section, but for --emit-relocs it is an virtual address.
- P->r_offset = RelocatedSection->OutSec->Addr +
+ P->r_offset = RelocatedSection->getOutputSection()->Addr +
RelocatedSection->getOffset(Rel.r_offset);
P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Body), Type,
Config->IsMips64EL);
@@ -602,7 +610,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
return;
}
- uint64_t AddrLoc = this->OutSec->Addr + Offset;
+ uint64_t AddrLoc = getParent()->Addr + Offset;
uint64_t SymVA = 0;
if (!Sym.isTls() || Out::TlsPhdr)
SymVA = SignExtend64<sizeof(typename ELFT::uint) * 8>(
@@ -735,6 +743,10 @@ EhInputSection::EhInputSection(elf::ObjectFile<ELFT> *F,
this->Live = true;
}
+SyntheticSection *EhInputSection::getParent() const {
+ return cast_or_null<SyntheticSection>(Parent);
+}
+
bool EhInputSection::classof(const SectionBase *S) {
return S->kind() == InputSectionBase::EHFrame;
}
@@ -803,6 +815,10 @@ static size_t findNull(ArrayRef<uint8_t> A, size_t EntSize) {
return StringRef::npos;
}
+SyntheticSection *MergeInputSection::getParent() const {
+ return cast_or_null<SyntheticSection>(Parent);
+}
+
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
OpenPOWER on IntegriCloud