Mercurial > hg > CbC > CbC_llvm
diff lld/ELF/MarkLive.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
line wrap: on
line diff
--- a/lld/ELF/MarkLive.cpp Mon May 25 11:55:54 2020 +0900 +++ b/lld/ELF/MarkLive.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -56,7 +56,7 @@ 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 @@ 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 @@ 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 @@ 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 or has the + // SHF_LINK_ORDER flag, we ignore the relocation as well because (a) if the + // associated text section is live, the LSDA will be retained due to section + // group/SHF_LINK_ORDER 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 | SHF_LINK_ORDER)) || + relSec->nextInSectionGroup))) enqueue(relSec, offset); return; } @@ -148,13 +157,10 @@ 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); } } @@ -255,12 +261,20 @@ scanEhFrameSection(*eh, eh->template rels<ELFT>()); } + if (sec->flags & SHF_GNU_RETAIN) { + enqueue(sec, 0); + continue; + } if (sec->flags & SHF_LINK_ORDER) continue; if (isReserved(sec) || script->shouldKeep(sec)) { enqueue(sec, 0); - } else if (isValidCIdentifier(sec->name)) { + } else if ((!config->zStartStopGC || sec->name.startswith("__libc_")) && + isValidCIdentifier(sec->name)) { + // As a workaround for glibc libc.a before 2.34 + // (https://sourceware.org/PR27492), retain __libc_atexit and similar + // sections regardless of zStartStopGC. cNamedSections[saver.save("__start_" + sec->name)].push_back(sec); cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec); } @@ -339,16 +353,16 @@ // 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 +384,11 @@ 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.