xref: /freebsd/contrib/llvm-project/lld/ELF/MarkLive.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
10b57cec5SDimitry Andric //===- MarkLive.cpp -------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements --gc-sections, which is a feature to remove unused
100b57cec5SDimitry Andric // sections from output. Unused sections are sections that are not reachable
110b57cec5SDimitry Andric // from known GC-root symbols or sections. Naturally the feature is
120b57cec5SDimitry Andric // implemented as a mark-sweep garbage collector.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric // Here's how it works. Each InputSectionBase has a "Live" bit. The bit is off
150b57cec5SDimitry Andric // by default. Starting with GC-root symbols or sections, markLive function
160b57cec5SDimitry Andric // defined in this file visits all reachable sections to set their Live
170b57cec5SDimitry Andric // bits. Writer will then ignore sections whose Live bits are off, so that
180b57cec5SDimitry Andric // such sections are not included into output.
190b57cec5SDimitry Andric //
200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #include "MarkLive.h"
2381ad6265SDimitry Andric #include "InputFiles.h"
240b57cec5SDimitry Andric #include "InputSection.h"
250b57cec5SDimitry Andric #include "LinkerScript.h"
260b57cec5SDimitry Andric #include "SymbolTable.h"
270b57cec5SDimitry Andric #include "Symbols.h"
280b57cec5SDimitry Andric #include "SyntheticSections.h"
290b57cec5SDimitry Andric #include "Target.h"
3004eeddc0SDimitry Andric #include "lld/Common/CommonLinkerContext.h"
310b57cec5SDimitry Andric #include "lld/Common/Strings.h"
320b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
330b57cec5SDimitry Andric #include "llvm/Object/ELF.h"
345ffd83dbSDimitry Andric #include "llvm/Support/TimeProfiler.h"
350b57cec5SDimitry Andric #include <vector>
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric using namespace llvm;
380b57cec5SDimitry Andric using namespace llvm::ELF;
390b57cec5SDimitry Andric using namespace llvm::object;
405ffd83dbSDimitry Andric using namespace llvm::support::endian;
415ffd83dbSDimitry Andric using namespace lld;
425ffd83dbSDimitry Andric using namespace lld::elf;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric namespace {
450b57cec5SDimitry Andric template <class ELFT> class MarkLive {
460b57cec5SDimitry Andric public:
MarkLive(unsigned partition)470b57cec5SDimitry Andric   MarkLive(unsigned partition) : partition(partition) {}
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   void run();
500b57cec5SDimitry Andric   void moveToMain();
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric private:
530b57cec5SDimitry Andric   void enqueue(InputSectionBase *sec, uint64_t offset);
540b57cec5SDimitry Andric   void markSymbol(Symbol *sym);
550b57cec5SDimitry Andric   void mark();
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   template <class RelTy>
58e8d8bef9SDimitry Andric   void resolveReloc(InputSectionBase &sec, RelTy &rel, bool fromFDE);
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   template <class RelTy>
610b57cec5SDimitry Andric   void scanEhFrameSection(EhInputSection &eh, ArrayRef<RelTy> rels);
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   // The index of the partition that we are currently processing.
640b57cec5SDimitry Andric   unsigned partition;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   // A list of sections to visit.
67e8d8bef9SDimitry Andric   SmallVector<InputSection *, 0> queue;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   // There are normally few input sections whose names are valid C
7004eeddc0SDimitry Andric   // identifiers, so we just store a SmallVector instead of a multimap.
7104eeddc0SDimitry Andric   DenseMap<StringRef, SmallVector<InputSectionBase *, 0>> cNamedSections;
720b57cec5SDimitry Andric };
730b57cec5SDimitry Andric } // namespace
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric template <class ELFT>
getAddend(InputSectionBase & sec,const typename ELFT::Rel & rel)760b57cec5SDimitry Andric static uint64_t getAddend(InputSectionBase &sec,
770b57cec5SDimitry Andric                           const typename ELFT::Rel &rel) {
78bdd1243dSDimitry Andric   return target->getImplicitAddend(sec.content().begin() + rel.r_offset,
790b57cec5SDimitry Andric                                    rel.getType(config->isMips64EL));
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric template <class ELFT>
getAddend(InputSectionBase & sec,const typename ELFT::Rela & rel)830b57cec5SDimitry Andric static uint64_t getAddend(InputSectionBase &sec,
840b57cec5SDimitry Andric                           const typename ELFT::Rela &rel) {
850b57cec5SDimitry Andric   return rel.r_addend;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric 
88*52418fc2SDimitry Andric // Currently, we assume all input CREL relocations have an explicit addend.
89*52418fc2SDimitry Andric template <class ELFT>
getAddend(InputSectionBase & sec,const typename ELFT::Crel & rel)90*52418fc2SDimitry Andric static uint64_t getAddend(InputSectionBase &sec,
91*52418fc2SDimitry Andric                           const typename ELFT::Crel &rel) {
92*52418fc2SDimitry Andric   return rel.r_addend;
93*52418fc2SDimitry Andric }
94*52418fc2SDimitry Andric 
950b57cec5SDimitry Andric template <class ELFT>
960b57cec5SDimitry Andric template <class RelTy>
resolveReloc(InputSectionBase & sec,RelTy & rel,bool fromFDE)970b57cec5SDimitry Andric void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
98e8d8bef9SDimitry Andric                                   bool fromFDE) {
990b57cec5SDimitry Andric   // If a symbol is referenced in a live section, it is used.
1000fca6ea1SDimitry Andric   Symbol &sym = sec.file->getRelocTargetSym(rel);
1010b57cec5SDimitry Andric   sym.used = true;
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   if (auto *d = dyn_cast<Defined>(&sym)) {
1040b57cec5SDimitry Andric     auto *relSec = dyn_cast_or_null<InputSectionBase>(d->section);
1050b57cec5SDimitry Andric     if (!relSec)
1060b57cec5SDimitry Andric       return;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric     uint64_t offset = d->value;
1090b57cec5SDimitry Andric     if (d->isSection())
1100b57cec5SDimitry Andric       offset += getAddend<ELFT>(sec, rel);
1110b57cec5SDimitry Andric 
112e8d8bef9SDimitry Andric     // fromFDE being true means this is referenced by a FDE in a .eh_frame
113e8d8bef9SDimitry Andric     // piece. The relocation points to the described function or to a LSDA. We
114e8d8bef9SDimitry Andric     // only need to keep the LSDA live, so ignore anything that points to
115fe6060f1SDimitry Andric     // executable sections. If the LSDA is in a section group or has the
116fe6060f1SDimitry Andric     // SHF_LINK_ORDER flag, we ignore the relocation as well because (a) if the
117fe6060f1SDimitry Andric     // associated text section is live, the LSDA will be retained due to section
118fe6060f1SDimitry Andric     // group/SHF_LINK_ORDER rules (b) if the associated text section should be
119fe6060f1SDimitry Andric     // discarded, marking the LSDA will unnecessarily retain the text section.
120fe6060f1SDimitry Andric     if (!(fromFDE && ((relSec->flags & (SHF_EXECINSTR | SHF_LINK_ORDER)) ||
121fe6060f1SDimitry Andric                       relSec->nextInSectionGroup)))
1220b57cec5SDimitry Andric       enqueue(relSec, offset);
1230b57cec5SDimitry Andric     return;
1240b57cec5SDimitry Andric   }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   if (auto *ss = dyn_cast<SharedSymbol>(&sym))
1270b57cec5SDimitry Andric     if (!ss->isWeak())
12881ad6265SDimitry Andric       cast<SharedFile>(ss->file)->isNeeded = true;
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   for (InputSectionBase *sec : cNamedSections.lookup(sym.getName()))
1310b57cec5SDimitry Andric     enqueue(sec, 0);
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric // The .eh_frame section is an unfortunate special case.
1350b57cec5SDimitry Andric // The section is divided in CIEs and FDEs and the relocations it can have are
1360b57cec5SDimitry Andric // * CIEs can refer to a personality function.
1370b57cec5SDimitry Andric // * FDEs can refer to a LSDA
1380b57cec5SDimitry Andric // * FDEs refer to the function they contain information about
1390b57cec5SDimitry Andric // The last kind of relocation cannot keep the referred section alive, or they
1400b57cec5SDimitry Andric // would keep everything alive in a common object file. In fact, each FDE is
1410b57cec5SDimitry Andric // alive if the section it refers to is alive.
1420b57cec5SDimitry Andric // To keep things simple, in here we just ignore the last relocation kind. The
1430b57cec5SDimitry Andric // other two keep the referred section alive.
1440b57cec5SDimitry Andric //
1450b57cec5SDimitry Andric // A possible improvement would be to fully process .eh_frame in the middle of
1460b57cec5SDimitry Andric // the gc pass. With that we would be able to also gc some sections holding
1470b57cec5SDimitry Andric // LSDAs and personality functions if we found that they were unused.
1480b57cec5SDimitry Andric template <class ELFT>
1490b57cec5SDimitry Andric template <class RelTy>
scanEhFrameSection(EhInputSection & eh,ArrayRef<RelTy> rels)1500b57cec5SDimitry Andric void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &eh,
1510b57cec5SDimitry Andric                                         ArrayRef<RelTy> rels) {
152bdd1243dSDimitry Andric   for (const EhSectionPiece &cie : eh.cies)
153bdd1243dSDimitry Andric     if (cie.firstRelocation != unsigned(-1))
154bdd1243dSDimitry Andric       resolveReloc(eh, rels[cie.firstRelocation], false);
155bdd1243dSDimitry Andric   for (const EhSectionPiece &fde : eh.fdes) {
156bdd1243dSDimitry Andric     size_t firstRelI = fde.firstRelocation;
1570b57cec5SDimitry Andric     if (firstRelI == (unsigned)-1)
1580b57cec5SDimitry Andric       continue;
159bdd1243dSDimitry Andric     uint64_t pieceEnd = fde.inputOff + fde.size;
160e8d8bef9SDimitry Andric     for (size_t j = firstRelI, end2 = rels.size();
161e8d8bef9SDimitry Andric          j < end2 && rels[j].r_offset < pieceEnd; ++j)
1620b57cec5SDimitry Andric       resolveReloc(eh, rels[j], true);
1630b57cec5SDimitry Andric   }
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric // Some sections are used directly by the loader, so they should never be
1670b57cec5SDimitry Andric // garbage-collected. This function returns true if a given section is such
1680b57cec5SDimitry Andric // section.
isReserved(InputSectionBase * sec)1690b57cec5SDimitry Andric static bool isReserved(InputSectionBase *sec) {
1700b57cec5SDimitry Andric   switch (sec->type) {
1710b57cec5SDimitry Andric   case SHT_FINI_ARRAY:
1720b57cec5SDimitry Andric   case SHT_INIT_ARRAY:
1730b57cec5SDimitry Andric   case SHT_PREINIT_ARRAY:
1740b57cec5SDimitry Andric     return true;
175480093f4SDimitry Andric   case SHT_NOTE:
176480093f4SDimitry Andric     // SHT_NOTE sections in a group are subject to garbage collection.
177480093f4SDimitry Andric     return !sec->nextInSectionGroup;
1780b57cec5SDimitry Andric   default:
17904eeddc0SDimitry Andric     // Support SHT_PROGBITS .init_array (https://golang.org/issue/50295) and
18004eeddc0SDimitry Andric     // .init_array.N (https://github.com/rust-lang/rust/issues/92181) for a
18104eeddc0SDimitry Andric     // while.
1820b57cec5SDimitry Andric     StringRef s = sec->name;
18306c3fb27SDimitry Andric     return s == ".init" || s == ".fini" || s.starts_with(".init_array") ||
18406c3fb27SDimitry Andric            s == ".jcr" || s.starts_with(".ctors") || s.starts_with(".dtors");
1850b57cec5SDimitry Andric   }
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric template <class ELFT>
enqueue(InputSectionBase * sec,uint64_t offset)1890b57cec5SDimitry Andric void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset) {
1900b57cec5SDimitry Andric   // Usually, a whole section is marked as live or dead, but in mergeable
1910b57cec5SDimitry Andric   // (splittable) sections, each piece of data has independent liveness bit.
1920b57cec5SDimitry Andric   // So we explicitly tell it which offset is in use.
1930b57cec5SDimitry Andric   if (auto *ms = dyn_cast<MergeInputSection>(sec))
19481ad6265SDimitry Andric     ms->getSectionPiece(offset).live = true;
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   // Set Sec->Partition to the meet (i.e. the "minimum") of Partition and
1970b57cec5SDimitry Andric   // Sec->Partition in the following lattice: 1 < other < 0. If Sec->Partition
1980b57cec5SDimitry Andric   // doesn't change, we don't need to do anything.
1990b57cec5SDimitry Andric   if (sec->partition == 1 || sec->partition == partition)
2000b57cec5SDimitry Andric     return;
2010b57cec5SDimitry Andric   sec->partition = sec->partition ? 1 : partition;
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   // Add input section to the queue.
2040b57cec5SDimitry Andric   if (InputSection *s = dyn_cast<InputSection>(sec))
2050b57cec5SDimitry Andric     queue.push_back(s);
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric 
markSymbol(Symbol * sym)2080b57cec5SDimitry Andric template <class ELFT> void MarkLive<ELFT>::markSymbol(Symbol *sym) {
2090b57cec5SDimitry Andric   if (auto *d = dyn_cast_or_null<Defined>(sym))
2100b57cec5SDimitry Andric     if (auto *isec = dyn_cast_or_null<InputSectionBase>(d->section))
2110b57cec5SDimitry Andric       enqueue(isec, d->value);
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric // This is the main function of the garbage collector.
2150b57cec5SDimitry Andric // Starting from GC-root sections, this function visits all reachable
2160b57cec5SDimitry Andric // sections to set their "Live" bits.
run()2170b57cec5SDimitry Andric template <class ELFT> void MarkLive<ELFT>::run() {
2180b57cec5SDimitry Andric   // Add GC root symbols.
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   // Preserve externally-visible symbols if the symbols defined by this
22106c3fb27SDimitry Andric   // file can interpose other ELF file's symbols at runtime.
222bdd1243dSDimitry Andric   for (Symbol *sym : symtab.getSymbols())
2230b57cec5SDimitry Andric     if (sym->includeInDynsym() && sym->partition == partition)
2240b57cec5SDimitry Andric       markSymbol(sym);
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   // If this isn't the main partition, that's all that we need to preserve.
2270b57cec5SDimitry Andric   if (partition != 1) {
2280b57cec5SDimitry Andric     mark();
2290b57cec5SDimitry Andric     return;
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
232bdd1243dSDimitry Andric   markSymbol(symtab.find(config->entry));
233bdd1243dSDimitry Andric   markSymbol(symtab.find(config->init));
234bdd1243dSDimitry Andric   markSymbol(symtab.find(config->fini));
2350b57cec5SDimitry Andric   for (StringRef s : config->undefined)
236bdd1243dSDimitry Andric     markSymbol(symtab.find(s));
2370b57cec5SDimitry Andric   for (StringRef s : script->referencedSymbols)
238bdd1243dSDimitry Andric     markSymbol(symtab.find(s));
23906c3fb27SDimitry Andric   for (auto [symName, _] : symtab.cmseSymMap) {
24006c3fb27SDimitry Andric     markSymbol(symtab.cmseSymMap[symName].sym);
24106c3fb27SDimitry Andric     markSymbol(symtab.cmseSymMap[symName].acleSeSym);
24206c3fb27SDimitry Andric   }
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   // Mark .eh_frame sections as live because there are usually no relocations
2450b57cec5SDimitry Andric   // that point to .eh_frames. Otherwise, the garbage collector would drop
2460b57cec5SDimitry Andric   // all of them. We also want to preserve personality routines and LSDA
2470b57cec5SDimitry Andric   // referenced by .eh_frame sections, so we scan them for that here.
248bdd1243dSDimitry Andric   for (EhInputSection *eh : ctx.ehInputSections) {
249*52418fc2SDimitry Andric     const RelsOrRelas<ELFT> rels =
250*52418fc2SDimitry Andric         eh->template relsOrRelas<ELFT>(/*supportsCrel=*/false);
251349cc55cSDimitry Andric     if (rels.areRelocsRel())
252349cc55cSDimitry Andric       scanEhFrameSection(*eh, rels.rels);
253349cc55cSDimitry Andric     else if (rels.relas.size())
254349cc55cSDimitry Andric       scanEhFrameSection(*eh, rels.relas);
2550b57cec5SDimitry Andric   }
256bdd1243dSDimitry Andric   for (InputSectionBase *sec : ctx.inputSections) {
257fe6060f1SDimitry Andric     if (sec->flags & SHF_GNU_RETAIN) {
258fe6060f1SDimitry Andric       enqueue(sec, 0);
259fe6060f1SDimitry Andric       continue;
260fe6060f1SDimitry Andric     }
2610b57cec5SDimitry Andric     if (sec->flags & SHF_LINK_ORDER)
2620b57cec5SDimitry Andric       continue;
2630b57cec5SDimitry Andric 
2640eae32dcSDimitry Andric     // Usually, non-SHF_ALLOC sections are not removed even if they are
2650eae32dcSDimitry Andric     // unreachable through relocations because reachability is not a good signal
2660eae32dcSDimitry Andric     // whether they are garbage or not (e.g. there is usually no section
2670eae32dcSDimitry Andric     // referring to a .comment section, but we want to keep it.) When a
2680eae32dcSDimitry Andric     // non-SHF_ALLOC section is retained, we also retain sections dependent on
2690eae32dcSDimitry Andric     // it.
2700eae32dcSDimitry Andric     //
2710eae32dcSDimitry Andric     // Note on SHF_LINK_ORDER: Such sections contain metadata and they
2720eae32dcSDimitry Andric     // have a reverse dependency on the InputSection they are linked with.
2730eae32dcSDimitry Andric     // We are able to garbage collect them.
2740eae32dcSDimitry Andric     //
2750eae32dcSDimitry Andric     // Note on SHF_REL{,A}: Such sections reach here only when -r
2760eae32dcSDimitry Andric     // or --emit-reloc were given. And they are subject of garbage
2770eae32dcSDimitry Andric     // collection because, if we remove a text section, we also
2780eae32dcSDimitry Andric     // remove its relocation section.
2790eae32dcSDimitry Andric     //
2800eae32dcSDimitry Andric     // Note on nextInSectionGroup: The ELF spec says that group sections are
2810eae32dcSDimitry Andric     // included or omitted as a unit. We take the interpretation that:
2820eae32dcSDimitry Andric     //
2830eae32dcSDimitry Andric     // - Group members (nextInSectionGroup != nullptr) are subject to garbage
2840eae32dcSDimitry Andric     //   collection.
2850eae32dcSDimitry Andric     // - Groups members are retained or discarded as a unit.
2860eae32dcSDimitry Andric     if (!(sec->flags & SHF_ALLOC)) {
2870fca6ea1SDimitry Andric       if (!isStaticRelSecType(sec->type) && !sec->nextInSectionGroup) {
2880eae32dcSDimitry Andric         sec->markLive();
2890eae32dcSDimitry Andric         for (InputSection *isec : sec->dependentSections)
2900eae32dcSDimitry Andric           isec->markLive();
2910eae32dcSDimitry Andric       }
2920eae32dcSDimitry Andric     }
2930eae32dcSDimitry Andric 
2940eae32dcSDimitry Andric     // Preserve special sections and those which are specified in linker
2950eae32dcSDimitry Andric     // script KEEP command.
2960b57cec5SDimitry Andric     if (isReserved(sec) || script->shouldKeep(sec)) {
2970b57cec5SDimitry Andric       enqueue(sec, 0);
29806c3fb27SDimitry Andric     } else if ((!config->zStartStopGC || sec->name.starts_with("__libc_")) &&
299fe6060f1SDimitry Andric                isValidCIdentifier(sec->name)) {
300fe6060f1SDimitry Andric       // As a workaround for glibc libc.a before 2.34
301fe6060f1SDimitry Andric       // (https://sourceware.org/PR27492), retain __libc_atexit and similar
302fe6060f1SDimitry Andric       // sections regardless of zStartStopGC.
30304eeddc0SDimitry Andric       cNamedSections[saver().save("__start_" + sec->name)].push_back(sec);
30404eeddc0SDimitry Andric       cNamedSections[saver().save("__stop_" + sec->name)].push_back(sec);
3050b57cec5SDimitry Andric     }
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   mark();
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
mark()3110b57cec5SDimitry Andric template <class ELFT> void MarkLive<ELFT>::mark() {
3120b57cec5SDimitry Andric   // Mark all reachable sections.
3130b57cec5SDimitry Andric   while (!queue.empty()) {
3140b57cec5SDimitry Andric     InputSectionBase &sec = *queue.pop_back_val();
3150b57cec5SDimitry Andric 
316349cc55cSDimitry Andric     const RelsOrRelas<ELFT> rels = sec.template relsOrRelas<ELFT>();
317349cc55cSDimitry Andric     for (const typename ELFT::Rel &rel : rels.rels)
3180b57cec5SDimitry Andric       resolveReloc(sec, rel, false);
319349cc55cSDimitry Andric     for (const typename ELFT::Rela &rel : rels.relas)
3200b57cec5SDimitry Andric       resolveReloc(sec, rel, false);
321*52418fc2SDimitry Andric     for (const typename ELFT::Crel &rel : rels.crels)
322*52418fc2SDimitry Andric       resolveReloc(sec, rel, false);
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric     for (InputSectionBase *isec : sec.dependentSections)
3250b57cec5SDimitry Andric       enqueue(isec, 0);
326480093f4SDimitry Andric 
327480093f4SDimitry Andric     // Mark the next group member.
328480093f4SDimitry Andric     if (sec.nextInSectionGroup)
329480093f4SDimitry Andric       enqueue(sec.nextInSectionGroup, 0);
3300b57cec5SDimitry Andric   }
3310b57cec5SDimitry Andric }
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric // Move the sections for some symbols to the main partition, specifically ifuncs
3340b57cec5SDimitry Andric // (because they can result in an IRELATIVE being added to the main partition's
3350b57cec5SDimitry Andric // GOT, which means that the ifunc must be available when the main partition is
3360b57cec5SDimitry Andric // loaded) and TLS symbols (because we only know how to correctly process TLS
3370b57cec5SDimitry Andric // relocations for the main partition).
33885868e8aSDimitry Andric //
33985868e8aSDimitry Andric // We also need to move sections whose names are C identifiers that are referred
34085868e8aSDimitry Andric // to from __start_/__stop_ symbols because there will only be one set of
34185868e8aSDimitry Andric // symbols for the whole program.
moveToMain()3420b57cec5SDimitry Andric template <class ELFT> void MarkLive<ELFT>::moveToMain() {
343bdd1243dSDimitry Andric   for (ELFFileBase *file : ctx.objectFiles)
3440b57cec5SDimitry Andric     for (Symbol *s : file->getSymbols())
3450b57cec5SDimitry Andric       if (auto *d = dyn_cast<Defined>(s))
3460b57cec5SDimitry Andric         if ((d->type == STT_GNU_IFUNC || d->type == STT_TLS) && d->section &&
3470b57cec5SDimitry Andric             d->section->isLive())
3480b57cec5SDimitry Andric           markSymbol(s);
3490b57cec5SDimitry Andric 
350bdd1243dSDimitry Andric   for (InputSectionBase *sec : ctx.inputSections) {
35185868e8aSDimitry Andric     if (!sec->isLive() || !isValidCIdentifier(sec->name))
35285868e8aSDimitry Andric       continue;
353bdd1243dSDimitry Andric     if (symtab.find(("__start_" + sec->name).str()) ||
354bdd1243dSDimitry Andric         symtab.find(("__stop_" + sec->name).str()))
35585868e8aSDimitry Andric       enqueue(sec, 0);
35685868e8aSDimitry Andric   }
35785868e8aSDimitry Andric 
3580b57cec5SDimitry Andric   mark();
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric // Before calling this function, Live bits are off for all
3620b57cec5SDimitry Andric // input sections. This function make some or all of them on
3630b57cec5SDimitry Andric // so that they are emitted to the output file.
markLive()3645ffd83dbSDimitry Andric template <class ELFT> void elf::markLive() {
3655ffd83dbSDimitry Andric   llvm::TimeTraceScope timeScope("markLive");
366349cc55cSDimitry Andric   // If --gc-sections is not given, retain all input sections.
3670b57cec5SDimitry Andric   if (!config->gcSections) {
3680b57cec5SDimitry Andric     // If a DSO defines a symbol referenced in a regular object, it is needed.
369bdd1243dSDimitry Andric     for (Symbol *sym : symtab.getSymbols())
3700b57cec5SDimitry Andric       if (auto *s = dyn_cast<SharedSymbol>(sym))
3710b57cec5SDimitry Andric         if (s->isUsedInRegularObj && !s->isWeak())
37281ad6265SDimitry Andric           cast<SharedFile>(s->file)->isNeeded = true;
3730b57cec5SDimitry Andric     return;
3740b57cec5SDimitry Andric   }
3750b57cec5SDimitry Andric 
376bdd1243dSDimitry Andric   for (InputSectionBase *sec : ctx.inputSections)
3771fd87a68SDimitry Andric     sec->markDead();
3781fd87a68SDimitry Andric 
3790b57cec5SDimitry Andric   // Follow the graph to mark all live sections.
3800b57cec5SDimitry Andric   for (unsigned curPart = 1; curPart <= partitions.size(); ++curPart)
3810b57cec5SDimitry Andric     MarkLive<ELFT>(curPart).run();
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   // If we have multiple partitions, some sections need to live in the main
3840b57cec5SDimitry Andric   // partition even if they were allocated to a loadable partition. Move them
3850b57cec5SDimitry Andric   // there now.
3860b57cec5SDimitry Andric   if (partitions.size() != 1)
3870b57cec5SDimitry Andric     MarkLive<ELFT>(1).moveToMain();
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   // Report garbage-collected sections.
3900b57cec5SDimitry Andric   if (config->printGcSections)
391bdd1243dSDimitry Andric     for (InputSectionBase *sec : ctx.inputSections)
3920b57cec5SDimitry Andric       if (!sec->isLive())
3930b57cec5SDimitry Andric         message("removing unused section " + toString(sec));
3940b57cec5SDimitry Andric }
3950b57cec5SDimitry Andric 
3965ffd83dbSDimitry Andric template void elf::markLive<ELF32LE>();
3975ffd83dbSDimitry Andric template void elf::markLive<ELF32BE>();
3985ffd83dbSDimitry Andric template void elf::markLive<ELF64LE>();
3995ffd83dbSDimitry Andric template void elf::markLive<ELF64BE>();
400