summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/EhFrame.cpp17
-rw-r--r--lld/ELF/EhFrame.h4
-rw-r--r--lld/ELF/InputSection.cpp2
-rw-r--r--lld/ELF/InputSection.h22
-rw-r--r--lld/ELF/MarkLive.cpp2
-rw-r--r--lld/ELF/SyntheticSections.cpp26
-rw-r--r--lld/ELF/SyntheticSections.h7
7 files changed, 47 insertions, 33 deletions
diff --git a/lld/ELF/EhFrame.cpp b/lld/ELF/EhFrame.cpp
index e29110ceab1..b0b141f6e4e 100644
--- a/lld/ELF/EhFrame.cpp
+++ b/lld/ELF/EhFrame.cpp
@@ -153,8 +153,9 @@ template <class ELFT> void EhReader<ELFT>::skipAugP() {
D = D.slice(Size);
}
-template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
- return EhReader<ELFT>(P->Sec, P->data()).getFdeEncoding();
+template <class ELFT>
+uint8_t elf::getFdeEncoding(EhInputSection *Sec, EhSectionPiece *Piece) {
+ return EhReader<ELFT>(Sec, Piece->data(Sec)).getFdeEncoding();
}
template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() {
@@ -205,7 +206,11 @@ template size_t elf::readEhRecordSize<ELF32BE>(InputSectionBase *S, size_t Off);
template size_t elf::readEhRecordSize<ELF64LE>(InputSectionBase *S, size_t Off);
template size_t elf::readEhRecordSize<ELF64BE>(InputSectionBase *S, size_t Off);
-template uint8_t elf::getFdeEncoding<ELF32LE>(EhSectionPiece *P);
-template uint8_t elf::getFdeEncoding<ELF32BE>(EhSectionPiece *P);
-template uint8_t elf::getFdeEncoding<ELF64LE>(EhSectionPiece *P);
-template uint8_t elf::getFdeEncoding<ELF64BE>(EhSectionPiece *P);
+template uint8_t elf::getFdeEncoding<ELF32LE>(EhInputSection *,
+ EhSectionPiece *);
+template uint8_t elf::getFdeEncoding<ELF32BE>(EhInputSection *,
+ EhSectionPiece *);
+template uint8_t elf::getFdeEncoding<ELF64LE>(EhInputSection *,
+ EhSectionPiece *);
+template uint8_t elf::getFdeEncoding<ELF64BE>(EhInputSection *,
+ EhSectionPiece *);
diff --git a/lld/ELF/EhFrame.h b/lld/ELF/EhFrame.h
index 07d1aaa3cbb..f33dab1cbb6 100644
--- a/lld/ELF/EhFrame.h
+++ b/lld/ELF/EhFrame.h
@@ -14,11 +14,13 @@
namespace lld {
namespace elf {
+class EhInputSection;
class InputSectionBase;
struct EhSectionPiece;
template <class ELFT> size_t readEhRecordSize(InputSectionBase *S, size_t Off);
-template <class ELFT> uint8_t getFdeEncoding(EhSectionPiece *P);
+template <class ELFT>
+uint8_t getFdeEncoding(EhInputSection *, EhSectionPiece *);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 016234abc90..0cf4b219632 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -870,7 +870,7 @@ void EhInputSection::split(ArrayRef<RelTy> Rels) {
unsigned RelI = 0;
for (size_t Off = 0, End = Data.size(); Off != End;) {
size_t Size = readEhRecordSize<ELFT>(this, Off);
- this->Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
+ this->Pieces.emplace_back(Off, Size, getReloc(Off, Size, Rels, RelI));
// The empty record is the end marker.
if (Size == 4)
break;
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 15436dfd37b..dd518e5a2e8 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -25,6 +25,7 @@ namespace lld {
namespace elf {
class DefinedCommon;
+class EhInputSection;
class SymbolBody;
struct SectionPiece;
@@ -262,17 +263,16 @@ private:
};
struct EhSectionPiece {
- EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
- unsigned FirstRelocation)
- : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
-
- ArrayRef<uint8_t> data() { return {Sec->Data.data() + this->InputOff, Size}; }
+ EhSectionPiece(size_t Off, uint32_t Size, unsigned FirstRelocation)
+ : InputOff(Off), Size(Size), FirstRelocation(FirstRelocation) {
+ assert(Off < UINT32_MAX && Size < UINT32_MAX);
+ }
- size_t InputOff;
- ssize_t OutputOff = -1;
- InputSectionBase *Sec;
+ ArrayRef<uint8_t> data(EhInputSection *Sec);
+ uint32_t InputOff;
+ int32_t OutputOff = -1;
uint32_t Size;
- unsigned FirstRelocation;
+ uint32_t FirstRelocation;
};
// This corresponds to a .eh_frame section of an input file.
@@ -292,6 +292,10 @@ public:
SyntheticSection *getParent() const;
};
+inline ArrayRef<uint8_t> EhSectionPiece::data(EhInputSection *Sec) {
+ return {Sec->Data.data() + InputOff, Size};
+}
+
// This is a section that is added directly to an output section
// instead of needing special combination via a synthetic section. This
// includes all input sections with the exceptions of SHF_MERGE and
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index f3438c86821..da7a72480e2 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -126,7 +126,7 @@ scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
unsigned FirstRelI = Piece.FirstRelocation;
if (FirstRelI == (unsigned)-1)
continue;
- if (read32<E>(Piece.data().data() + 4) == 0) {
+ if (read32<E>(Piece.data(&EH).data() + 4) == 0) {
// This is a CIE, we only need to worry about the first relocation. It is
// known to point to the personality function.
resolveReloc<ELFT>(EH, Rels[FirstRelI], Fn);
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index b13aa47fd63..c7aa392acb3 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -403,11 +403,11 @@ EhFrameSection<ELFT>::EhFrameSection()
// and where their relocations point to.
template <class ELFT>
template <class RelTy>
-CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Cie,
+CieRecord *EhFrameSection<ELFT>::addCie(EhInputSection *Sec,
+ EhSectionPiece &Cie,
ArrayRef<RelTy> Rels) {
- auto *Sec = cast<EhInputSection>(Cie.Sec);
const endianness E = ELFT::TargetEndianness;
- if (read32<E>(Cie.data().data() + 4) != 0)
+ if (read32<E>(Cie.data(Sec).data() + 4) != 0)
fatal(toString(Sec) + ": CIE expected at beginning of .eh_frame");
SymbolBody *Personality = nullptr;
@@ -417,10 +417,11 @@ CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Cie,
&Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
// Search for an existing CIE by CIE contents/relocation target pair.
- CieRecord *Rec = &CieMap[{Cie.data(), Personality}];
+ CieRecord *Rec = &CieMap[{Cie.data(Sec), Personality}];
// If not found, create a new one.
- if (Rec->Cie == nullptr) {
+ if (Rec->Sec == nullptr) {
+ Rec->Sec = Sec;
Rec->Cie = &Cie;
CieRecords.push_back(Rec);
}
@@ -431,9 +432,8 @@ CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Cie,
// points to a live function.
template <class ELFT>
template <class RelTy>
-bool EhFrameSection<ELFT>::isFdeLive(EhSectionPiece &Fde,
+bool EhFrameSection<ELFT>::isFdeLive(EhInputSection *Sec, EhSectionPiece &Fde,
ArrayRef<RelTy> Rels) {
- auto *Sec = cast<EhInputSection>(Fde.Sec);
unsigned FirstRelI = Fde.FirstRelocation;
// An FDE should point to some function because FDEs are to describe
@@ -469,9 +469,9 @@ void EhFrameSection<ELFT>::addSectionAux(EhInputSection *Sec,
return;
size_t Offset = Piece.InputOff;
- uint32_t ID = read32<E>(Piece.data().data() + 4);
+ uint32_t ID = read32<E>(Piece.data(Sec).data() + 4);
if (ID == 0) {
- OffsetToCie[Offset] = addCie(Piece, Rels);
+ OffsetToCie[Offset] = addCie(Sec, Piece, Rels);
continue;
}
@@ -480,7 +480,7 @@ void EhFrameSection<ELFT>::addSectionAux(EhInputSection *Sec,
if (!Rec)
fatal(toString(Sec) + ": invalid CIE reference");
- if (!isFdeLive(Piece, Rels))
+ if (!isFdeLive(Sec, Piece, Rels))
continue;
Rec->Fdes.push_back(&Piece);
NumFdes++;
@@ -586,11 +586,11 @@ template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) {
const endianness E = ELFT::TargetEndianness;
for (CieRecord *Rec : CieRecords) {
size_t CieOffset = Rec->Cie->OutputOff;
- writeCieFde<ELFT>(Buf + CieOffset, Rec->Cie->data());
+ writeCieFde<ELFT>(Buf + CieOffset, Rec->Cie->data(Rec->Sec));
for (EhSectionPiece *Fde : Rec->Fdes) {
size_t Off = Fde->OutputOff;
- writeCieFde<ELFT>(Buf + Off, Fde->data());
+ writeCieFde<ELFT>(Buf + Off, Fde->data(Rec->Sec));
// FDE's second word should have the offset to an associated CIE.
// Write it.
@@ -606,7 +606,7 @@ template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) {
// we obtain two addresses and pass them to EhFrameHdr object.
if (In<ELFT>::EhFrameHdr) {
for (CieRecord *Rec : CieRecords) {
- uint8_t Enc = getFdeEncoding<ELFT>(Rec->Cie);
+ uint8_t Enc = getFdeEncoding<ELFT>(Rec->Sec, Rec->Cie);
for (EhSectionPiece *Fde : Rec->Fdes) {
uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 31766794d41..b9c794511f8 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -59,6 +59,7 @@ public:
};
struct CieRecord {
+ EhInputSection *Sec = nullptr;
EhSectionPiece *Cie = nullptr;
std::vector<EhSectionPiece *> Fdes;
};
@@ -93,10 +94,12 @@ private:
void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels);
template <class RelTy>
- CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
+ CieRecord *addCie(EhInputSection *Sec, EhSectionPiece &Piece,
+ ArrayRef<RelTy> Rels);
template <class RelTy>
- bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
+ bool isFdeLive(EhInputSection *Sec, EhSectionPiece &Piece,
+ ArrayRef<RelTy> Rels);
uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc);
OpenPOWER on IntegriCloud