ELF: Perform per-section .ARM.exidx processing during combineEhFrameSections(). NFCI.
And rename the function to combineEhSections(). This makes the processing of .ARM.exidx even more similar to .eh_frame and means that we can avoid an additional loop over InputSections. Differential Revision: https://reviews.llvm.org/D60026 llvm-svn: 357417
This commit is contained in:
parent
b06935fa8c
commit
a9e847238e
|
@ -3041,37 +3041,7 @@ MipsRldMapSection::MipsRldMapSection()
|
||||||
|
|
||||||
ARMExidxSyntheticSection::ARMExidxSyntheticSection()
|
ARMExidxSyntheticSection::ARMExidxSyntheticSection()
|
||||||
: SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
|
: SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
|
||||||
Config->Wordsize, ".ARM.exidx") {
|
Config->Wordsize, ".ARM.exidx") {}
|
||||||
for (InputSectionBase *&IS : InputSections) {
|
|
||||||
if (isa<InputSection>(IS) && IS->Type == SHT_ARM_EXIDX) {
|
|
||||||
ExidxSections.push_back(cast<InputSection>(IS));
|
|
||||||
IS = nullptr;
|
|
||||||
} else if (IS->Live && isa<InputSection>(IS) &&
|
|
||||||
IS->kind() != SectionBase::Synthetic &&
|
|
||||||
(IS->Flags & SHF_ALLOC) && (IS->Flags & SHF_EXECINSTR) &&
|
|
||||||
IS->getSize() > 0) {
|
|
||||||
ExecutableSections.push_back(cast<InputSection>(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<InputSection>(IS) && IS->Type == SHT_REL) {
|
|
||||||
InputSection *RS = cast<InputSection>(IS);
|
|
||||||
if (InputSectionBase *EX = RS->getRelocatedSection())
|
|
||||||
if (isa<InputSection>(EX) && EX->Type == SHT_ARM_EXIDX)
|
|
||||||
IS = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<InputSectionBase *> &V = InputSections;
|
|
||||||
V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
static InputSection *findExidxSection(InputSection *IS) {
|
static InputSection *findExidxSection(InputSection *IS) {
|
||||||
for (InputSection *D : IS->DependentSections)
|
for (InputSection *D : IS->DependentSections)
|
||||||
|
@ -3080,21 +3050,31 @@ static InputSection *findExidxSection(InputSection *IS) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMExidxSyntheticSection::setSizeAndOffsets() {
|
bool ARMExidxSyntheticSection::addSection(InputSection *IS) {
|
||||||
size_t Offset = 0;
|
if (IS->Type == SHT_ARM_EXIDX) {
|
||||||
Size = 0;
|
ExidxSections.push_back(IS);
|
||||||
for (InputSection *IS : ExecutableSections) {
|
return true;
|
||||||
if (InputSection *D = findExidxSection(IS)) {
|
|
||||||
D->OutSecOff = Offset;
|
|
||||||
D->Parent = getParent();
|
|
||||||
Offset += D->getSize();
|
|
||||||
Empty = false;
|
|
||||||
} else {
|
|
||||||
Offset += 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Size includes Sentinel.
|
|
||||||
Size = Offset + 8;
|
if ((IS->Flags & SHF_ALLOC) && (IS->Flags & SHF_EXECINSTR) &&
|
||||||
|
IS->getSize() > 0) {
|
||||||
|
ExecutableSections.push_back(IS);
|
||||||
|
if (Empty && findExidxSection(IS))
|
||||||
|
Empty = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<InputSection>(EX) && EX->Type == SHT_ARM_EXIDX)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// References to .ARM.Extab Sections have bit 31 clear and are not the
|
// References to .ARM.Extab Sections have bit 31 clear and are not the
|
||||||
|
@ -3181,7 +3161,20 @@ void ARMExidxSyntheticSection::finalizeContents() {
|
||||||
}
|
}
|
||||||
ExecutableSections = std::move(SelectedSections);
|
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 {
|
InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
|
||||||
|
|
|
@ -975,6 +975,11 @@ public:
|
||||||
class ARMExidxSyntheticSection : public SyntheticSection {
|
class ARMExidxSyntheticSection : public SyntheticSection {
|
||||||
public:
|
public:
|
||||||
ARMExidxSyntheticSection();
|
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; }
|
size_t getSize() const override { return Size; }
|
||||||
void writeTo(uint8_t *Buf) override;
|
void writeTo(uint8_t *Buf) override;
|
||||||
bool isNeeded() const override { return !Empty; }
|
bool isNeeded() const override { return !Empty; }
|
||||||
|
@ -989,9 +994,6 @@ public:
|
||||||
std::vector<InputSection *> ExidxSections;
|
std::vector<InputSection *> ExidxSections;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Derive Size from contents of ExecutableSections, including any linker
|
|
||||||
// generated sentinels. Also set the OutSecOff of the ExidxSections.
|
|
||||||
void setSizeAndOffsets();
|
|
||||||
size_t Size;
|
size_t Size;
|
||||||
|
|
||||||
// Empty if ExecutableSections contains no dependent .ARM.exidx sections.
|
// Empty if ExecutableSections contains no dependent .ARM.exidx sections.
|
||||||
|
|
|
@ -152,14 +152,18 @@ template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> static void combineEhFrameSections() {
|
template <class ELFT> static void combineEhSections() {
|
||||||
for (InputSectionBase *&S : InputSections) {
|
for (InputSectionBase *&S : InputSections) {
|
||||||
EhInputSection *ES = dyn_cast<EhInputSection>(S);
|
if (!S->Live)
|
||||||
if (!ES || !ES->Live)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
In.EhFrame->addSection<ELFT>(ES);
|
if (auto *ES = dyn_cast<EhInputSection>(S)) {
|
||||||
S = nullptr;
|
In.EhFrame->addSection<ELFT>(ES);
|
||||||
|
S = nullptr;
|
||||||
|
} else if (S->kind() == SectionBase::Regular && In.ARMExidx &&
|
||||||
|
In.ARMExidx->addSection(cast<InputSection>(S))) {
|
||||||
|
S = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<InputSectionBase *> &V = InputSections;
|
std::vector<InputSectionBase *> &V = InputSections;
|
||||||
|
@ -465,8 +469,11 @@ template <class ELFT> void Writer<ELFT>::run() {
|
||||||
// Such sections are of type input section.
|
// Such sections are of type input section.
|
||||||
createSyntheticSections<ELFT>();
|
createSyntheticSections<ELFT>();
|
||||||
|
|
||||||
|
// 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)
|
if (!Config->Relocatable)
|
||||||
combineEhFrameSections<ELFT>();
|
combineEhSections<ELFT>();
|
||||||
|
|
||||||
// We want to process linker script commands. When SECTIONS command
|
// We want to process linker script commands. When SECTIONS command
|
||||||
// is given we let it create sections.
|
// is given we let it create sections.
|
||||||
|
|
Loading…
Reference in New Issue