mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-23 07:52:06 +00:00
[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 llvm-svn: 369890
This commit is contained in:
parent
debcac9fef
commit
1681ceb2c4
@ -402,7 +402,7 @@ bool EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) {
|
||||
// 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(EhInputSection *sec, ArrayRef<RelTy> rels) {
|
||||
}
|
||||
}
|
||||
|
||||
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 EhFrameSection::addSection(InputSectionBase *c) {
|
||||
|
||||
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, 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;
|
||||
@ -3267,17 +3290,14 @@ static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
|
||||
// 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);
|
||||
|
@ -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);
|
||||
|
@ -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 combineEhSections() {
|
||||
|
||||
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>::run() {
|
||||
// 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.
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user