aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/SyntheticSections.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/SyntheticSections.cpp')
-rw-r--r--lld/ELF/SyntheticSections.cpp66
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;
}