diff options
-rw-r--r-- | lld/ELF/EhFrame.cpp | 17 | ||||
-rw-r--r-- | lld/ELF/EhFrame.h | 4 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/InputSection.h | 22 | ||||
-rw-r--r-- | lld/ELF/MarkLive.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 26 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 7 |
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); |