diff options
Diffstat (limited to 'contrib/llvm-project/lld/ELF/MarkLive.cpp')
-rw-r--r-- | contrib/llvm-project/lld/ELF/MarkLive.cpp | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/contrib/llvm-project/lld/ELF/MarkLive.cpp b/contrib/llvm-project/lld/ELF/MarkLive.cpp index 28e13e8c1234..35220e168df3 100644 --- a/contrib/llvm-project/lld/ELF/MarkLive.cpp +++ b/contrib/llvm-project/lld/ELF/MarkLive.cpp @@ -56,7 +56,7 @@ private: void mark(); template <class RelTy> - void resolveReloc(InputSectionBase &sec, RelTy &rel, bool isLSDA); + void resolveReloc(InputSectionBase &sec, RelTy &rel, bool fromFDE); template <class RelTy> void scanEhFrameSection(EhInputSection &eh, ArrayRef<RelTy> rels); @@ -65,7 +65,7 @@ private: unsigned partition; // A list of sections to visit. - SmallVector<InputSection *, 256> queue; + SmallVector<InputSection *, 0> queue; // There are normally few input sections whose names are valid C // identifiers, so we just store a std::vector instead of a multimap. @@ -89,7 +89,7 @@ static uint64_t getAddend(InputSectionBase &sec, template <class ELFT> template <class RelTy> void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel, - bool isLSDA) { + bool fromFDE) { Symbol &sym = sec.getFile<ELFT>()->getRelocTargetSym(rel); // If a symbol is referenced in a live section, it is used. @@ -104,7 +104,16 @@ void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel, if (d->isSection()) offset += getAddend<ELFT>(sec, rel); - if (!isLSDA || !(relSec->flags & SHF_EXECINSTR)) + // fromFDE being true means this is referenced by a FDE in a .eh_frame + // piece. The relocation points to the described function or to a LSDA. We + // only need to keep the LSDA live, so ignore anything that points to + // executable sections. If the LSDA is in a section group, we ignore the + // relocation as well because (a) if the associated text section is live, + // the LSDA will be retained due to section group rules (b) if the + // associated text section should be discarded, marking the LSDA will + // unnecessarily retain the text section. + if (!(fromFDE && + ((relSec->flags & SHF_EXECINSTR) || relSec->nextInSectionGroup))) enqueue(relSec, offset); return; } @@ -148,13 +157,10 @@ void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &eh, continue; } - // This is a FDE. The relocations point to the described function or to - // a LSDA. We only need to keep the LSDA alive, so ignore anything that - // points to executable sections. uint64_t pieceEnd = piece.inputOff + piece.size; - for (size_t j = firstRelI, end2 = rels.size(); j < end2; ++j) - if (rels[j].r_offset < pieceEnd) - resolveReloc(eh, rels[j], true); + for (size_t j = firstRelI, end2 = rels.size(); + j < end2 && rels[j].r_offset < pieceEnd; ++j) + resolveReloc(eh, rels[j], true); } } @@ -339,16 +345,16 @@ template <class ELFT> void elf::markLive() { // Otherwise, do mark-sweep GC. // - // The -gc-sections option works only for SHF_ALLOC sections - // (sections that are memory-mapped at runtime). So we can - // unconditionally make non-SHF_ALLOC sections alive except - // SHF_LINK_ORDER and SHT_REL/SHT_RELA sections. + // The -gc-sections option works only for SHF_ALLOC sections (sections that + // are memory-mapped at runtime). So we can unconditionally make non-SHF_ALLOC + // sections alive except SHF_LINK_ORDER, SHT_REL/SHT_RELA sections, and + // sections in a group. // // Usually, non-SHF_ALLOC sections are not removed even if they are - // unreachable through relocations because reachability is not - // a good signal whether they are garbage or not (e.g. there is - // usually no section referring to a .comment section, but we - // want to keep it.). + // unreachable through relocations because reachability is not a good signal + // whether they are garbage or not (e.g. there is usually no section referring + // to a .comment section, but we want to keep it.) When a non-SHF_ALLOC + // section is retained, we also retain sections dependent on it. // // Note on SHF_LINK_ORDER: Such sections contain metadata and they // have a reverse dependency on the InputSection they are linked with. @@ -370,8 +376,11 @@ template <class ELFT> void elf::markLive() { bool isLinkOrder = (sec->flags & SHF_LINK_ORDER); bool isRel = (sec->type == SHT_REL || sec->type == SHT_RELA); - if (!isAlloc && !isLinkOrder && !isRel && !sec->nextInSectionGroup) + if (!isAlloc && !isLinkOrder && !isRel && !sec->nextInSectionGroup) { sec->markLive(); + for (InputSection *isec : sec->dependentSections) + isec->markLive(); + } } // Follow the graph to mark all live sections. |