// 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.
}
}
-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);
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) {
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;
// 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
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);
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.
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))) {
// 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.