diff options
Diffstat (limited to 'lld/ELF/SyntheticSections.cpp')
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 66 |
1 files changed, 20 insertions, 46 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 457a794..bbf4b29 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -403,12 +403,12 @@ EhFrameSection::EhFrameSection(Ctx &ctx) // Search for an existing CIE record or create a new one. // CIE records from input object files are uniquified by their contents // and where their relocations point to. -template <class RelTy> -CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, ArrayRef<RelTy> rels) { +CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, + ArrayRef<Relocation> rels) { Symbol *personality = nullptr; unsigned firstRelI = cie.firstRelocation; if (firstRelI != (unsigned)-1) - personality = &cie.sec->file->getRelocTargetSym(rels[firstRelI]); + personality = rels[firstRelI].sym; // Search for an existing CIE by CIE contents/relocation target pair. CieRecord *&rec = cieMap[{cie.data(), personality}]; @@ -424,25 +424,20 @@ CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, ArrayRef<RelTy> rels) { // There is one FDE per function. Returns a non-null pointer to the function // symbol if the given FDE points to a live function. -template <class RelTy> -Defined *EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) { - auto *sec = cast<EhInputSection>(fde.sec); - unsigned firstRelI = fde.firstRelocation; - +Defined *EhFrameSection::isFdeLive(EhSectionPiece &fde, + ArrayRef<Relocation> rels) { // An FDE should point to some function because FDEs are to describe // functions. That's however not always the case due to an issue of // ld.gold with -r. ld.gold may discard only functions and leave their // corresponding FDEs, which results in creating bad .eh_frame sections. // To deal with that, we ignore such FDEs. + unsigned firstRelI = fde.firstRelocation; if (firstRelI == (unsigned)-1) return nullptr; - const RelTy &rel = rels[firstRelI]; - Symbol &b = sec->file->getRelocTargetSym(rel); - // FDEs for garbage-collected or merged-by-ICF sections, or sections in // another partition, are dead. - if (auto *d = dyn_cast<Defined>(&b)) + if (auto *d = dyn_cast<Defined>(rels[firstRelI].sym)) if (!d->folded && d->section && d->section->partition == partition) return d; return nullptr; @@ -452,13 +447,13 @@ Defined *EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) { // is one CIE record per input object file which is followed by // 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::addRecords(EhInputSection *sec, ArrayRef<RelTy> rels) { +template <endianness e> void EhFrameSection::addRecords(EhInputSection *sec) { + auto rels = sec->rels; offsetToCie.clear(); for (EhSectionPiece &cie : sec->cies) - offsetToCie[cie.inputOff] = addCie<RelTy>(cie, rels); + offsetToCie[cie.inputOff] = addCie(cie, rels); for (EhSectionPiece &fde : sec->fdes) { - uint32_t id = endian::read32<ELFT::Endianness>(fde.data().data() + 4); + uint32_t id = endian::read32<e>(fde.data().data() + 4); CieRecord *rec = offsetToCie[fde.inputOff + 4 - id]; if (!rec) Fatal(ctx) << sec << ": invalid CIE reference"; @@ -470,23 +465,11 @@ void EhFrameSection::addRecords(EhInputSection *sec, ArrayRef<RelTy> rels) { } } -template <class ELFT> -void EhFrameSection::addSectionAux(EhInputSection *sec) { - if (!sec->isLive()) - return; - const RelsOrRelas<ELFT> rels = - sec->template relsOrRelas<ELFT>(/*supportsCrel=*/false); - if (rels.areRelocsRel()) - addRecords<ELFT>(sec, rels.rels); - else - addRecords<ELFT>(sec, rels.relas); -} - // Used by ICF<ELFT>::handleLSDA(). This function is very similar to // EhFrameSection::addRecords(). -template <class ELFT, class RelTy> +template <class ELFT> void EhFrameSection::iterateFDEWithLSDAAux( - EhInputSection &sec, ArrayRef<RelTy> rels, DenseSet<size_t> &ciesWithLSDA, + EhInputSection &sec, DenseSet<size_t> &ciesWithLSDA, llvm::function_ref<void(InputSection &)> fn) { for (EhSectionPiece &cie : sec.cies) if (hasLSDA(cie)) @@ -497,7 +480,7 @@ void EhFrameSection::iterateFDEWithLSDAAux( continue; // The CIE has a LSDA argument. Call fn with d's section. - if (Defined *d = isFdeLive(fde, rels)) + if (Defined *d = isFdeLive(fde, sec.rels)) if (auto *s = dyn_cast_or_null<InputSection>(d->section)) fn(*s); } @@ -509,12 +492,7 @@ void EhFrameSection::iterateFDEWithLSDA( DenseSet<size_t> ciesWithLSDA; for (EhInputSection *sec : sections) { ciesWithLSDA.clear(); - const RelsOrRelas<ELFT> rels = - sec->template relsOrRelas<ELFT>(/*supportsCrel=*/false); - if (rels.areRelocsRel()) - iterateFDEWithLSDAAux<ELFT>(*sec, rels.rels, ciesWithLSDA, fn); - else - iterateFDEWithLSDAAux<ELFT>(*sec, rels.relas, ciesWithLSDA, fn); + iterateFDEWithLSDAAux<ELFT>(*sec, ciesWithLSDA, fn); } } @@ -531,20 +509,16 @@ void EhFrameSection::finalizeContents() { 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); + if (sec->isLive()) + addRecords<endianness::little>(sec); break; + case ELF32BEKind: case ELF64BEKind: for (EhInputSection *sec : sections) - addSectionAux<ELF64BE>(sec); + if (sec->isLive()) + addRecords<endianness::big>(sec); break; } |