Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -76,7 +76,7 @@ return SyntheticSection::classof(d) && d->name == ".eh_frame"; } - template void addSection(InputSectionBase *s); + void addSection(InputSectionBase *s); std::vector sections; size_t numFdes = 0; @@ -97,7 +97,9 @@ uint64_t size = 0; template - void addSectionAux(EhInputSection *s, llvm::ArrayRef rels); + void addRecords(EhInputSection *s, llvm::ArrayRef rels); + template + void addSectionAux(EhInputSection *s); template CieRecord *addCie(EhSectionPiece &piece, ArrayRef rels); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -402,7 +402,7 @@ // a list of FDEs. This function searches an existing CIE or create a new // one and associates FDEs to the CIE. template -void EhFrameSection::addSectionAux(EhInputSection *sec, ArrayRef rels) { +void EhFrameSection::addRecords(EhInputSection *sec, ArrayRef rels) { offsetToCie.clear(); for (EhSectionPiece &piece : sec->pieces) { // The empty record is the end marker. @@ -428,7 +428,17 @@ } } -template void EhFrameSection::addSection(InputSectionBase *c) { +template +void EhFrameSection::addSectionAux(EhInputSection *sec) { + if (!sec->isLive()) + return; + if (sec->areRelocsRela) + addRecords(sec, sec->template relas()); + else + addRecords(sec, sec->template rels()); +} + +void EhFrameSection::addSection(InputSectionBase *c) { auto *sec = cast(c); sec->parent = this; @@ -437,14 +447,6 @@ for (auto *ds : sec->dependentSections) dependentSections.push_back(ds); - - if (sec->pieces.empty()) - return; - - if (sec->areRelocsRela) - addSectionAux(sec, sec->template relas()); - else - addSectionAux(sec, sec->template rels()); } static void writeCieFde(uint8_t *buf, ArrayRef d) { @@ -461,6 +463,28 @@ void EhFrameSection::finalizeContents() { assert(!this->size); // Not finalized. + + switch (config->ekind) { + case ELFNoneKind: + llvm_unreachable("invalid ekind"); + case ELF32LEKind: + for (EhInputSection *sec : sections) + addSectionAux(sec); + break; + case ELF32BEKind: + for (EhInputSection *sec : sections) + addSectionAux(sec); + break; + case ELF64LEKind: + for (EhInputSection *sec : sections) + addSectionAux(sec); + break; + case ELF64BEKind: + for (EhInputSection *sec : sections) + addSectionAux(sec); + break; + } + size_t off = 0; for (CieRecord *rec : cieRecords) { rec->cie->outputOff = off; @@ -3267,17 +3291,14 @@ // 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. The linker script SECTIONS command may + // have a /DISCARD/ entry 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 +3660,6 @@ template void elf::splitSections(); template void elf::splitSections(); -template void EhFrameSection::addSection(InputSectionBase *); -template void EhFrameSection::addSection(InputSectionBase *); -template void EhFrameSection::addSection(InputSectionBase *); -template void EhFrameSection::addSection(InputSectionBase *); - template void PltSection::addEntry(Symbol &Sym); template void PltSection::addEntry(Symbol &Sym); template void PltSection::addEntry(Symbol &Sym); Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -19,6 +19,7 @@ class InputFile; class OutputSection; class InputSectionBase; +void combineEhSections(); template void writeResult(); // This describes a program header entry. Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -174,7 +174,7 @@ newSections.end()); } -template 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 @@ Partition &part = s->getPartition(); if (auto *es = dyn_cast(s)) { - part.ehFrame->addSection(es); + part.ehFrame->addSection(es); s = nullptr; } else if (s->kind() == SectionBase::Regular && part.armExidx && part.armExidx->addSection(cast(s))) { @@ -552,7 +552,7 @@ // into synthetic sections. Do that now so that they aren't assigned to // output sections in the usual way. if (!config->relocatable) - combineEhSections(); + combineEhSections(); // We want to process linker script commands. When SECTIONS command // is given we let it create sections.