summaryrefslogtreecommitdiff
path: root/lld/ELF/MarkLive.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-08-10 16:21:04 +0000
committerRui Ueyama <ruiu@google.com>2017-08-10 16:21:04 +0000
commit2a43d5149ca2e310f41a567ca2267a50074f346a (patch)
treea73470e707891f493b8065186bb52a3a91bb1a7f /lld/ELF/MarkLive.cpp
parent2d0f880014d97070c202ff21ff956680696d479b (diff)
Remove ResolvedReloc.
ResolvedReloc struct is always passed to a callback function and not stored anywhere. That is, in effect, we use the struct to pack multiple arguments to one argument, which doesn't make much sense. This patch removes the struct and passes the members to the callback directly.
Diffstat (limited to 'lld/ELF/MarkLive.cpp')
-rw-r--r--lld/ELF/MarkLive.cpp76
1 files changed, 36 insertions, 40 deletions
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 38dda922553..448d44269c0 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -42,15 +42,6 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
-namespace {
-// A resolved relocation. The Sec and Offset fields are set if the relocation
-// was resolved to an offset within a section.
-struct ResolvedReloc {
- InputSectionBase *Sec;
- uint64_t Offset;
-};
-} // end anonymous namespace
-
template <class ELFT>
static typename ELFT::uint getAddend(InputSectionBase &Sec,
const typename ELFT::Rel &Rel) {
@@ -70,7 +61,7 @@ static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections;
template <class ELFT, class RelT>
static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
- std::function<void(ResolvedReloc)> Fn) {
+ std::function<void(InputSectionBase *, uint64_t)> Fn) {
SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
if (auto *Sym = dyn_cast<DefinedCommon>(&B)) {
@@ -81,22 +72,23 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
if (!D->Section)
return;
- typename ELFT::uint Offset = D->Value;
+ uint64_t Offset = D->Value;
if (D->isSection())
Offset += getAddend<ELFT>(Sec, Rel);
- Fn({cast<InputSectionBase>(D->Section), Offset});
+ Fn(cast<InputSectionBase>(D->Section), Offset);
return;
}
if (auto *U = dyn_cast<Undefined>(&B))
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
- Fn({Sec, 0});
+ Fn(Sec, 0);
}
// Calls Fn for each section that Sec refers to via relocations.
template <class ELFT>
-static void forEachSuccessor(InputSection &Sec,
- std::function<void(ResolvedReloc)> Fn) {
+static void
+forEachSuccessor(InputSection &Sec,
+ std::function<void(InputSectionBase *, uint64_t)> Fn) {
if (Sec.AreRelocsRela) {
for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>())
resolveReloc<ELFT>(Sec, Rel, Fn);
@@ -104,8 +96,9 @@ static void forEachSuccessor(InputSection &Sec,
for (const typename ELFT::Rel &Rel : Sec.template rels<ELFT>())
resolveReloc<ELFT>(Sec, Rel, Fn);
}
+
for (InputSectionBase *IS : Sec.DependentSections)
- Fn({IS, 0});
+ Fn(IS, 0);
}
// The .eh_frame section is an unfortunate special case.
@@ -123,9 +116,11 @@ static void forEachSuccessor(InputSection &Sec,
// the gc pass. With that we would be able to also gc some sections holding
// LSDAs and personality functions if we found that they were unused.
template <class ELFT, class RelTy>
-static void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
- std::function<void(ResolvedReloc)> Enqueue) {
+static void
+scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
+ std::function<void(InputSectionBase *, uint64_t)> Fn) {
const endianness E = ELFT::TargetEndianness;
+
for (unsigned I = 0, N = EH.Pieces.size(); I < N; ++I) {
EhSectionPiece &Piece = EH.Pieces[I];
unsigned FirstRelI = Piece.FirstRelocation;
@@ -134,7 +129,7 @@ static void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
if (read32<E>(Piece.data().data() + 4) == 0) {
// This is a CIE, we only need to worry about the first relocation. It is
// known to point to the personality function.
- resolveReloc<ELFT>(EH, Rels[FirstRelI], Enqueue);
+ resolveReloc<ELFT>(EH, Rels[FirstRelI], Fn);
continue;
}
// This is a FDE. The relocations point to the described function or to
@@ -145,20 +140,20 @@ static void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
const RelTy &Rel = Rels[I2];
if (Rel.r_offset >= PieceEnd)
break;
- resolveReloc<ELFT>(EH, Rels[I2], [&](ResolvedReloc R) {
- if (!R.Sec || R.Sec == &InputSection::Discarded)
- return;
- if (R.Sec->Flags & SHF_EXECINSTR)
- return;
- Enqueue({R.Sec, 0});
- });
+ resolveReloc<ELFT>(EH, Rels[I2],
+ [&](InputSectionBase *Sec, uint64_t Offset) {
+ if (Sec && Sec != &InputSection::Discarded &&
+ !(Sec->Flags & SHF_EXECINSTR))
+ Fn(Sec, 0);
+ });
}
}
}
template <class ELFT>
-static void scanEhFrameSection(EhInputSection &EH,
- std::function<void(ResolvedReloc)> Enqueue) {
+static void
+scanEhFrameSection(EhInputSection &EH,
+ std::function<void(InputSectionBase *, uint64_t)> Fn) {
if (!EH.NumRelocations)
return;
@@ -167,9 +162,9 @@ static void scanEhFrameSection(EhInputSection &EH,
EH.split<ELFT>();
if (EH.AreRelocsRela)
- scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Enqueue);
+ scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Fn);
else
- scanEhFrameSection<ELFT>(EH, EH.template rels<ELFT>(), Enqueue);
+ scanEhFrameSection<ELFT>(EH, EH.template rels<ELFT>(), Fn);
}
// We do not garbage-collect two types of sections:
@@ -200,36 +195,37 @@ template <class ELFT> void elf::markLive() {
SmallVector<InputSection *, 256> Q;
CNamedSections.clear();
- auto Enqueue = [&](ResolvedReloc R) {
+ auto Enqueue = [&](InputSectionBase *Sec, uint64_t Offset) {
// Skip over discarded sections. This in theory shouldn't happen, because
// the ELF spec doesn't allow a relocation to point to a deduplicated
// COMDAT section directly. Unfortunately this happens in practice (e.g.
// .eh_frame) so we need to add a check.
- if (R.Sec == &InputSection::Discarded)
+ if (Sec == &InputSection::Discarded)
return;
// We don't gc non alloc sections.
- if (!(R.Sec->Flags & SHF_ALLOC))
+ if (!(Sec->Flags & SHF_ALLOC))
return;
// Usually, a whole section is marked as live or dead, but in mergeable
// (splittable) sections, each piece of data has independent liveness bit.
// So we explicitly tell it which offset is in use.
- if (auto *MS = dyn_cast<MergeInputSection>(R.Sec))
- MS->markLiveAt(R.Offset);
+ if (auto *MS = dyn_cast<MergeInputSection>(Sec))
+ MS->markLiveAt(Offset);
- if (R.Sec->Live)
+ if (Sec->Live)
return;
- R.Sec->Live = true;
+ Sec->Live = true;
+
// Add input section to the queue.
- if (InputSection *S = dyn_cast<InputSection>(R.Sec))
+ if (InputSection *S = dyn_cast<InputSection>(Sec))
Q.push_back(S);
};
auto MarkSymbol = [&](SymbolBody *Sym) {
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) {
if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
- Enqueue({IS, D->Value});
+ Enqueue(IS, D->Value);
return;
}
if (auto *S = dyn_cast_or_null<DefinedCommon>(Sym))
@@ -262,7 +258,7 @@ template <class ELFT> void elf::markLive() {
if (Sec->Flags & SHF_LINK_ORDER)
continue;
if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))
- Enqueue({Sec, 0});
+ Enqueue(Sec, 0);
else if (isValidCIdentifier(Sec->Name)) {
CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);