[lld] r369890 - [ELF] EhFrameSection: postpone FDE liveness check to finalizeSections
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 26 03:32:12 PDT 2019
Author: maskray
Date: Mon Aug 26 03:32:12 2019
New Revision: 369890
URL: http://llvm.org/viewvc/llvm-project?rev=369890&view=rev
Log:
[ELF] EhFrameSection: postpone FDE liveness check to finalizeSections
EhFrameSection::addSection checks liveness of FDE early. This makes it
infeasible to move combineEhSections() before ICF.
Postpone the check to EhFrameSection::finalizeContents(). This is what
ARMExidxSyntheticSection does and it will make a subsequent patch D66717
simpler.
Reviewed By: ruiu
Differential Revision: https://reviews.llvm.org/D66727
Modified:
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
lld/trunk/ELF/Writer.h
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=369890&r1=369889&r2=369890&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Aug 26 03:32:12 2019
@@ -402,7 +402,7 @@ bool EhFrameSection::isFdeLive(EhSection
// a list of FDEs. This function searches an existing CIE or create a new
// one and associates FDEs to the CIE.
template <class ELFT, class RelTy>
-void EhFrameSection::addSectionAux(EhInputSection *sec, ArrayRef<RelTy> rels) {
+void EhFrameSection::addRecords(EhInputSection *sec, ArrayRef<RelTy> rels) {
offsetToCie.clear();
for (EhSectionPiece &piece : sec->pieces) {
// The empty record is the end marker.
@@ -428,8 +428,17 @@ void EhFrameSection::addSectionAux(EhInp
}
}
-template <class ELFT> void EhFrameSection::addSection(InputSectionBase *c) {
- auto *sec = cast<EhInputSection>(c);
+template <class ELFT>
+void EhFrameSection::addSectionAux(EhInputSection *sec) {
+ if (!sec->isLive())
+ return;
+ if (sec->areRelocsRela)
+ addRecords<ELFT>(sec, sec->template relas<ELFT>());
+ else
+ addRecords<ELFT>(sec, sec->template rels<ELFT>());
+}
+
+void EhFrameSection::addSection(EhInputSection *sec) {
sec->parent = this;
alignment = std::max(alignment, sec->alignment);
@@ -437,14 +446,6 @@ template <class ELFT> void EhFrameSectio
for (auto *ds : sec->dependentSections)
dependentSections.push_back(ds);
-
- if (sec->pieces.empty())
- return;
-
- if (sec->areRelocsRela)
- addSectionAux<ELFT>(sec, sec->template relas<ELFT>());
- else
- addSectionAux<ELFT>(sec, sec->template rels<ELFT>());
}
static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
@@ -461,6 +462,28 @@ static void writeCieFde(uint8_t *buf, Ar
void EhFrameSection::finalizeContents() {
assert(!this->size); // Not finalized.
+
+ switch (config->ekind) {
+ case ELFNoneKind:
+ llvm_unreachable("invalid ekind");
+ case ELF32LEKind:
+ for (EhInputSection *sec : sections)
+ addSectionAux<ELF32LE>(sec);
+ break;
+ case ELF32BEKind:
+ for (EhInputSection *sec : sections)
+ addSectionAux<ELF32BE>(sec);
+ break;
+ case ELF64LEKind:
+ for (EhInputSection *sec : sections)
+ addSectionAux<ELF64LE>(sec);
+ break;
+ case ELF64BEKind:
+ for (EhInputSection *sec : sections)
+ addSectionAux<ELF64BE>(sec);
+ break;
+ }
+
size_t off = 0;
for (CieRecord *rec : cieRecords) {
rec->cie->outputOff = off;
@@ -3267,17 +3290,14 @@ static bool isDuplicateArmExidxSec(Input
// with the highest address and any InputSections that have mergeable
// .ARM.exidx table entries are removed from it.
void ARMExidxSyntheticSection::finalizeContents() {
- if (script->hasSectionsCommand) {
- // The executableSections and exidxSections that we use to derive the
- // final contents of this SyntheticSection are populated before the
- // linker script assigns InputSections to OutputSections. The linker script
- // SECTIONS command may have a /DISCARD/ entry that removes executable
- // InputSections and their dependent .ARM.exidx section that we recorded
- // earlier.
- auto isDiscarded = [](const InputSection *isec) { return !isec->isLive(); };
- llvm::erase_if(executableSections, isDiscarded);
- llvm::erase_if(exidxSections, isDiscarded);
- }
+ // The executableSections and exidxSections that we use to derive the final
+ // contents of this SyntheticSection are populated before
+ // processSectionCommands() and ICF. A /DISCARD/ entry in SECTIONS command or
+ // ICF may remove executable InputSections and their dependent .ARM.exidx
+ // section that we recorded earlier.
+ auto isDiscarded = [](const InputSection *isec) { return !isec->isLive(); };
+ llvm::erase_if(executableSections, isDiscarded);
+ llvm::erase_if(exidxSections, isDiscarded);
// Sort the executable sections that may or may not have associated
// .ARM.exidx sections by order of ascending address. This requires the
@@ -3639,11 +3659,6 @@ template void elf::splitSections<ELF32BE
template void elf::splitSections<ELF64LE>();
template void elf::splitSections<ELF64BE>();
-template void EhFrameSection::addSection<ELF32LE>(InputSectionBase *);
-template void EhFrameSection::addSection<ELF32BE>(InputSectionBase *);
-template void EhFrameSection::addSection<ELF64LE>(InputSectionBase *);
-template void EhFrameSection::addSection<ELF64BE>(InputSectionBase *);
-
template void PltSection::addEntry<ELF32LE>(Symbol &Sym);
template void PltSection::addEntry<ELF32BE>(Symbol &Sym);
template void PltSection::addEntry<ELF64LE>(Symbol &Sym);
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=369890&r1=369889&r2=369890&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Aug 26 03:32:12 2019
@@ -76,7 +76,7 @@ public:
return SyntheticSection::classof(d) && d->name == ".eh_frame";
}
- template <class ELFT> void addSection(InputSectionBase *s);
+ void addSection(EhInputSection *sec);
std::vector<EhInputSection *> sections;
size_t numFdes = 0;
@@ -97,7 +97,9 @@ private:
uint64_t size = 0;
template <class ELFT, class RelTy>
- void addSectionAux(EhInputSection *s, llvm::ArrayRef<RelTy> rels);
+ void addRecords(EhInputSection *s, llvm::ArrayRef<RelTy> rels);
+ template <class ELFT>
+ void addSectionAux(EhInputSection *s);
template <class ELFT, class RelTy>
CieRecord *addCie(EhSectionPiece &piece, ArrayRef<RelTy> rels);
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=369890&r1=369889&r2=369890&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Aug 26 03:32:12 2019
@@ -174,7 +174,7 @@ static void copySectionsIntoPartitions()
newSections.end());
}
-template <class ELFT> static void combineEhSections() {
+void elf::combineEhSections() {
for (InputSectionBase *&s : inputSections) {
// Ignore dead sections and the partition end marker (.part.end),
// whose partition number is out of bounds.
@@ -183,7 +183,7 @@ template <class ELFT> static void combin
Partition &part = s->getPartition();
if (auto *es = dyn_cast<EhInputSection>(s)) {
- part.ehFrame->addSection<ELFT>(es);
+ part.ehFrame->addSection(es);
s = nullptr;
} else if (s->kind() == SectionBase::Regular && part.armExidx &&
part.armExidx->addSection(cast<InputSection>(s))) {
@@ -552,7 +552,7 @@ template <class ELFT> void Writer<ELFT>:
// into synthetic sections. Do that now so that they aren't assigned to
// output sections in the usual way.
if (!config->relocatable)
- combineEhSections<ELFT>();
+ combineEhSections();
// We want to process linker script commands. When SECTIONS command
// is given we let it create sections.
Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=369890&r1=369889&r2=369890&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Mon Aug 26 03:32:12 2019
@@ -19,6 +19,7 @@ namespace elf {
class InputFile;
class OutputSection;
class InputSectionBase;
+void combineEhSections();
template <class ELFT> void writeResult();
// This describes a program header entry.
More information about the llvm-commits
mailing list