[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