aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/MarkLive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/MarkLive.cpp')
-rw-r--r--lld/ELF/MarkLive.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 02ab6d18e537..bb0105c28928 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -165,9 +165,11 @@ static bool isReserved(InputSectionBase *sec) {
switch (sec->type) {
case SHT_FINI_ARRAY:
case SHT_INIT_ARRAY:
- case SHT_NOTE:
case SHT_PREINIT_ARRAY:
return true;
+ case SHT_NOTE:
+ // SHT_NOTE sections in a group are subject to garbage collection.
+ return !sec->nextInSectionGroup;
default:
StringRef s = sec->name;
return s.startswith(".ctors") || s.startswith(".dtors") ||
@@ -217,10 +219,9 @@ template <class ELFT> void MarkLive<ELFT>::run() {
// Preserve externally-visible symbols if the symbols defined by this
// file can interrupt other ELF file's symbols at runtime.
- symtab->forEachSymbol([&](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (sym->includeInDynsym() && sym->partition == partition)
markSymbol(sym);
- });
// If this isn't the main partition, that's all that we need to preserve.
if (partition != 1) {
@@ -283,6 +284,10 @@ template <class ELFT> void MarkLive<ELFT>::mark() {
for (InputSectionBase *isec : sec.dependentSections)
enqueue(isec, 0);
+
+ // Mark the next group member.
+ if (sec.nextInSectionGroup)
+ enqueue(sec.nextInSectionGroup, 0);
}
}
@@ -324,15 +329,14 @@ template <class ELFT> void markLive() {
sec->markLive();
// If a DSO defines a symbol referenced in a regular object, it is needed.
- symtab->forEachSymbol([](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (auto *s = dyn_cast<SharedSymbol>(sym))
if (s->isUsedInRegularObj && !s->isWeak())
s->getFile().isNeeded = true;
- });
return;
}
- // Otheriwse, do mark-sweep GC.
+ // 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
@@ -353,12 +357,19 @@ template <class ELFT> void markLive() {
// or -emit-reloc were given. And they are subject of garbage
// collection because, if we remove a text section, we also
// remove its relocation section.
+ //
+ // Note on nextInSectionGroup: The ELF spec says that group sections are
+ // included or omitted as a unit. We take the interpretation that:
+ //
+ // - Group members (nextInSectionGroup != nullptr) are subject to garbage
+ // collection.
+ // - Groups members are retained or discarded as a unit.
for (InputSectionBase *sec : inputSections) {
bool isAlloc = (sec->flags & SHF_ALLOC);
bool isLinkOrder = (sec->flags & SHF_LINK_ORDER);
bool isRel = (sec->type == SHT_REL || sec->type == SHT_RELA);
- if (!isAlloc && !isLinkOrder && !isRel)
+ if (!isAlloc && !isLinkOrder && !isRel && !sec->nextInSectionGroup)
sec->markLive();
}