diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-05-31 20:17:44 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-05-31 20:17:44 +0000 |
| commit | db5e56f7b2c8fd96321bed5b829e77b6e699bfdf (patch) | |
| tree | 4caf5d172b7bd90a4842c904d9936f942c1e82e3 /lld/ELF/InputSection.cpp | |
| parent | 1d4cde62832ac8cd8d4955a864bc794523f932d9 (diff) | |
| download | bcm5719-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.cpp | 38 |
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) { |

