ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
//===- MarkLive.cpp -------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements --gc-sections, which is a feature to remove unused
|
|
|
|
// sections from output. Unused sections are sections that are not reachable
|
|
|
|
// from known GC-root symbols or sections. Naturally the feature is
|
|
|
|
// implemented as a mark-sweep garbage collector.
|
|
|
|
//
|
|
|
|
// Here's how it works. Each InputSectionBase has a "Live" bit. The bit is off
|
|
|
|
// by default. Starting with GC-root symbols or sections, markLive function
|
|
|
|
// defined in this file visits all reachable sections to set their Live
|
|
|
|
// bits. Writer will then ignore sections whose Live bits are off, so that
|
|
|
|
// such sections are removed from output.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "InputSection.h"
|
|
|
|
#include "OutputSections.h"
|
|
|
|
#include "SymbolTable.h"
|
|
|
|
#include "Symbols.h"
|
|
|
|
#include "Writer.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/Object/ELF.h"
|
|
|
|
#include <functional>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace llvm::ELF;
|
|
|
|
using namespace llvm::object;
|
|
|
|
|
|
|
|
using namespace lld;
|
|
|
|
using namespace lld::elf2;
|
|
|
|
|
|
|
|
// Calls Fn for each section that Sec refers to.
|
|
|
|
template <class ELFT>
|
|
|
|
static void forEachSuccessor(InputSection<ELFT> *Sec,
|
|
|
|
std::function<void(InputSectionBase<ELFT> *)> Fn) {
|
2015-10-28 05:51:13 +08:00
|
|
|
typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
|
|
|
|
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
|
2015-10-28 05:51:13 +08:00
|
|
|
|
|
|
|
ELFFile<ELFT> &Obj = Sec->getFile()->getObj();
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
for (const Elf_Shdr *RelSec : Sec->RelocSections) {
|
2015-10-28 05:51:13 +08:00
|
|
|
if (RelSec->sh_type == SHT_RELA) {
|
|
|
|
for (const Elf_Rela &RI : Obj.relas(RelSec))
|
|
|
|
if (InputSectionBase<ELFT> *Succ = Sec->getRelocTarget(RI))
|
|
|
|
Fn(Succ);
|
|
|
|
} else {
|
|
|
|
for (const Elf_Rel &RI : Obj.rels(RelSec))
|
|
|
|
if (InputSectionBase<ELFT> *Succ = Sec->getRelocTarget(RI))
|
|
|
|
Fn(Succ);
|
|
|
|
}
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sections listed below are special because they are used by the loader
|
|
|
|
// just by being in an ELF file. They should not be garbage-collected.
|
|
|
|
template <class ELFT> static bool isReserved(InputSectionBase<ELFT> *Sec) {
|
|
|
|
switch (Sec->getSectionHdr()->sh_type) {
|
|
|
|
case SHT_FINI_ARRAY:
|
|
|
|
case SHT_INIT_ARRAY:
|
|
|
|
case SHT_NOTE:
|
|
|
|
case SHT_PREINIT_ARRAY:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
StringRef S = Sec->getSectionName();
|
2015-10-23 05:42:05 +08:00
|
|
|
return S.startswith(".init") || S.startswith(".fini") ||
|
2015-11-10 01:44:10 +08:00
|
|
|
S.startswith(".jcr");
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT> void lld::elf2::markLive(SymbolTable<ELFT> *Symtab) {
|
2015-11-13 03:42:43 +08:00
|
|
|
SmallVector<InputSection<ELFT> *, 256> Q;
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
|
|
|
|
auto Enqueue = [&](InputSectionBase<ELFT> *Sec) {
|
|
|
|
if (!Sec || Sec->Live)
|
|
|
|
return;
|
|
|
|
Sec->Live = true;
|
2015-11-13 03:42:43 +08:00
|
|
|
if (InputSection<ELFT> *S = dyn_cast<InputSection<ELFT>>(Sec))
|
|
|
|
Q.push_back(S);
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
auto MarkSymbol = [&](SymbolBody *Sym) {
|
|
|
|
if (Sym)
|
2015-10-23 07:10:25 +08:00
|
|
|
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(Sym->repl()))
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
Enqueue(&D->Section);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Add GC root symbols.
|
|
|
|
MarkSymbol(Config->EntrySym);
|
|
|
|
MarkSymbol(Symtab->find(Config->Init));
|
|
|
|
MarkSymbol(Symtab->find(Config->Fini));
|
|
|
|
for (StringRef S : Config->Undefined)
|
|
|
|
MarkSymbol(Symtab->find(S));
|
|
|
|
|
|
|
|
// Preserve externally-visible symbols if the symbols defined by this
|
|
|
|
// file could override other ELF file's symbols at runtime.
|
|
|
|
if (Config->Shared || Config->ExportDynamic) {
|
|
|
|
for (const std::pair<StringRef, Symbol *> &P : Symtab->getSymbols()) {
|
|
|
|
SymbolBody *B = P.second->Body;
|
|
|
|
if (B->getVisibility() == STV_DEFAULT)
|
|
|
|
MarkSymbol(B);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Preserve special sections.
|
2015-11-10 01:44:10 +08:00
|
|
|
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles()) {
|
|
|
|
for (InputSectionBase<ELFT> *Sec : F->getSections()) {
|
2015-11-13 03:45:58 +08:00
|
|
|
if (!Sec || Sec == &InputSection<ELFT>::Discarded)
|
|
|
|
continue;
|
|
|
|
if (isReserved(Sec))
|
|
|
|
Enqueue(Sec);
|
|
|
|
else if (Sec->getSectionName() == ".eh_frame")
|
|
|
|
// .eh_frame is special. It should be marked live so that we don't
|
|
|
|
// drop it, but it should not keep any section alive.
|
|
|
|
Sec->Live = true;
|
2015-11-10 01:44:10 +08:00
|
|
|
}
|
|
|
|
}
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
|
|
|
|
// Mark all reachable sections.
|
|
|
|
while (!Q.empty())
|
2015-11-13 03:42:43 +08:00
|
|
|
forEachSuccessor<ELFT>(Q.pop_back_val(), Enqueue);
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template void lld::elf2::markLive<ELF32LE>(SymbolTable<ELF32LE> *);
|
|
|
|
template void lld::elf2::markLive<ELF32BE>(SymbolTable<ELF32BE> *);
|
|
|
|
template void lld::elf2::markLive<ELF64LE>(SymbolTable<ELF64LE> *);
|
|
|
|
template void lld::elf2::markLive<ELF64BE>(SymbolTable<ELF64BE> *);
|