Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -975,6 +975,11 @@ class ARMExidxSyntheticSection : public SyntheticSection { public: ARMExidxSyntheticSection(); + + // Add an input section to the ARMExidxSyntheticSection. Returns whether the + // section needs to be removed from the main input section list. + bool addSection(InputSection *IS); + size_t getSize() const override { return Size; } void writeTo(uint8_t *Buf) override; bool isNeeded() const override { return !Empty; } @@ -989,9 +994,6 @@ std::vector ExidxSections; private: - // Derive Size from contents of ExecutableSections, including any linker - // generated sentinels. Also set the OutSecOff of the ExidxSections. - void setSizeAndOffsets(); size_t Size; // Empty if ExecutableSections contains no dependent .ARM.exidx sections. Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -3041,37 +3041,7 @@ ARMExidxSyntheticSection::ARMExidxSyntheticSection() : SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX, - Config->Wordsize, ".ARM.exidx") { - for (InputSectionBase *&IS : InputSections) { - if (isa(IS) && IS->Type == SHT_ARM_EXIDX) { - ExidxSections.push_back(cast(IS)); - IS = nullptr; - } else if (IS->Live && isa(IS) && - IS->kind() != SectionBase::Synthetic && - (IS->Flags & SHF_ALLOC) && (IS->Flags & SHF_EXECINSTR) && - IS->getSize() > 0) { - ExecutableSections.push_back(cast(IS)); - } - } - setSizeAndOffsets(); - - // FIXME: we do not output a relocation section when --emit-relocs is used - // as we do not have relocation sections for linker generated table entries - // and we would have to erase at a late stage relocations from merged entries. - // Given that exception tables are already position independent and a binary - // analyzer could derive the relocations we choose to erase the relocations. - if (Config->EmitRelocs) - for (InputSectionBase *&IS : InputSections) - if (IS && isa(IS) && IS->Type == SHT_REL) { - InputSection *RS = cast(IS); - if (InputSectionBase *EX = RS->getRelocatedSection()) - if (isa(EX) && EX->Type == SHT_ARM_EXIDX) - IS = nullptr; - } - - std::vector &V = InputSections; - V.erase(std::remove(V.begin(), V.end(), nullptr), V.end()); -} + Config->Wordsize, ".ARM.exidx") {} static InputSection *findExidxSection(InputSection *IS) { for (InputSection *D : IS->DependentSections) @@ -3080,21 +3050,31 @@ return nullptr; } -void ARMExidxSyntheticSection::setSizeAndOffsets() { - size_t Offset = 0; - Size = 0; - for (InputSection *IS : ExecutableSections) { - if (InputSection *D = findExidxSection(IS)) { - D->OutSecOff = Offset; - D->Parent = getParent(); - Offset += D->getSize(); +bool ARMExidxSyntheticSection::addSection(InputSection *IS) { + if (IS->Type == SHT_ARM_EXIDX) { + ExidxSections.push_back(IS); + return true; + } + + if ((IS->Flags & SHF_ALLOC) && (IS->Flags & SHF_EXECINSTR) && + IS->getSize() > 0) { + ExecutableSections.push_back(IS); + if (Empty && findExidxSection(IS)) Empty = false; - } else { - Offset += 8; - } + return false; } - // Size includes Sentinel. - Size = Offset + 8; + + // FIXME: we do not output a relocation section when --emit-relocs is used + // as we do not have relocation sections for linker generated table entries + // and we would have to erase at a late stage relocations from merged entries. + // Given that exception tables are already position independent and a binary + // analyzer could derive the relocations we choose to erase the relocations. + if (Config->EmitRelocs && IS->Type == SHT_REL) + if (InputSectionBase *EX = IS->getRelocatedSection()) + if (isa(EX) && EX->Type == SHT_ARM_EXIDX) + return true; + + return false; } // References to .ARM.Extab Sections have bit 31 clear and are not the @@ -3181,7 +3161,20 @@ } ExecutableSections = std::move(SelectedSections); } - setSizeAndOffsets(); + + size_t Offset = 0; + Size = 0; + for (InputSection *IS : ExecutableSections) { + if (InputSection *D = findExidxSection(IS)) { + D->OutSecOff = Offset; + D->Parent = getParent(); + Offset += D->getSize(); + } else { + Offset += 8; + } + } + // Size includes Sentinel. + Size = Offset + 8; } InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const { Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -152,14 +152,18 @@ }); } -template static void combineEhFrameSections() { +template static void combineEhSections() { for (InputSectionBase *&S : InputSections) { - EhInputSection *ES = dyn_cast(S); - if (!ES || !ES->Live) + if (!S->Live) continue; - In.EhFrame->addSection(ES); - S = nullptr; + if (auto *ES = dyn_cast(S)) { + In.EhFrame->addSection(ES); + S = nullptr; + } else if (S->kind() == SectionBase::Regular && In.ARMExidx && + In.ARMExidx->addSection(cast(S))) { + S = nullptr; + } } std::vector &V = InputSections; @@ -465,8 +469,11 @@ // Such sections are of type input section. createSyntheticSections(); + // Some input sections that are used for exception handling need to be moved + // into synthetic sections. Do that now so that they aren't assigned to + // output sections in the usual way. if (!Config->Relocatable) - combineEhFrameSections(); + combineEhSections(); // We want to process linker script commands. When SECTIONS command // is given we let it create sections.