[ELF] --gc-sections: combine two iterations over inputSections
There is a slight speed-up.
This commit is contained in:
parent
4bf31659fa
commit
4374824ccf
|
@ -244,8 +244,6 @@ template <class ELFT> void MarkLive<ELFT>::run() {
|
|||
for (StringRef s : script->referencedSymbols)
|
||||
markSymbol(symtab->find(s));
|
||||
|
||||
// Preserve special sections and those which are specified in linker
|
||||
// script KEEP command.
|
||||
for (InputSectionBase *sec : inputSections) {
|
||||
// Mark .eh_frame sections as live because there are usually no relocations
|
||||
// that point to .eh_frames. Otherwise, the garbage collector would drop
|
||||
|
@ -259,6 +257,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
|
|||
scanEhFrameSection(*eh, rels.rels);
|
||||
else if (rels.relas.size())
|
||||
scanEhFrameSection(*eh, rels.relas);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sec->flags & SHF_GNU_RETAIN) {
|
||||
|
@ -268,6 +267,39 @@ template <class ELFT> void MarkLive<ELFT>::run() {
|
|||
if (sec->flags & SHF_LINK_ORDER)
|
||||
continue;
|
||||
|
||||
// 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.) 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.
|
||||
// We are able to garbage collect them.
|
||||
//
|
||||
// Note on SHF_REL{,A}: Such sections reach here only when -r
|
||||
// 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.
|
||||
if (!(sec->flags & SHF_ALLOC)) {
|
||||
bool isRel = sec->type == SHT_REL || sec->type == SHT_RELA;
|
||||
if (!isRel && !sec->nextInSectionGroup) {
|
||||
sec->markLive();
|
||||
for (InputSection *isec : sec->dependentSections)
|
||||
isec->markLive();
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve special sections and those which are specified in linker
|
||||
// script KEEP command.
|
||||
if (isReserved(sec) || script->shouldKeep(sec)) {
|
||||
enqueue(sec, 0);
|
||||
} else if ((!config->zStartStopGC || sec->name.startswith("__libc_")) &&
|
||||
|
@ -377,17 +409,6 @@ template <class ELFT> void elf::markLive() {
|
|||
// - 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 && !sec->nextInSectionGroup) {
|
||||
sec->markLive();
|
||||
for (InputSection *isec : sec->dependentSections)
|
||||
isec->markLive();
|
||||
}
|
||||
}
|
||||
|
||||
// Follow the graph to mark all live sections.
|
||||
for (unsigned curPart = 1; curPart <= partitions.size(); ++curPart)
|
||||
|
|
Loading…
Reference in New Issue