Index: lld/ELF/EhFrame.h =================================================================== --- lld/ELF/EhFrame.h +++ lld/ELF/EhFrame.h @@ -14,11 +14,13 @@ namespace lld { namespace elf { +class EhInputSection; class InputSectionBase; struct EhSectionPiece; template size_t readEhRecordSize(InputSectionBase *S, size_t Off); -template uint8_t getFdeEncoding(EhSectionPiece *P); +template +uint8_t getFdeEncoding(EhInputSection *, EhSectionPiece *); } // namespace elf } // namespace lld Index: lld/ELF/EhFrame.cpp =================================================================== --- lld/ELF/EhFrame.cpp +++ lld/ELF/EhFrame.cpp @@ -153,8 +153,9 @@ D = D.slice(Size); } -template uint8_t elf::getFdeEncoding(EhSectionPiece *P) { - return EhReader(P->Sec, P->data()).getFdeEncoding(); +template +uint8_t elf::getFdeEncoding(EhInputSection *Sec, EhSectionPiece *Piece) { + return EhReader(Sec, Piece->data(Sec)).getFdeEncoding(); } template uint8_t EhReader::getFdeEncoding() { @@ -205,7 +206,11 @@ template size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off); template size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off); -template uint8_t elf::getFdeEncoding(EhSectionPiece *P); -template uint8_t elf::getFdeEncoding(EhSectionPiece *P); -template uint8_t elf::getFdeEncoding(EhSectionPiece *P); -template uint8_t elf::getFdeEncoding(EhSectionPiece *P); +template uint8_t elf::getFdeEncoding(EhInputSection *, + EhSectionPiece *); +template uint8_t elf::getFdeEncoding(EhInputSection *, + EhSectionPiece *); +template uint8_t elf::getFdeEncoding(EhInputSection *, + EhSectionPiece *); +template uint8_t elf::getFdeEncoding(EhInputSection *, + EhSectionPiece *); Index: lld/ELF/InputSection.h =================================================================== --- lld/ELF/InputSection.h +++ lld/ELF/InputSection.h @@ -25,6 +25,7 @@ namespace elf { class DefinedCommon; +class EhInputSection; class SymbolBody; struct SectionPiece; @@ -262,17 +263,16 @@ }; struct EhSectionPiece { - EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size, - unsigned FirstRelocation) - : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {} - - ArrayRef 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 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 @@ SyntheticSection *getParent() const; }; +inline ArrayRef 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 Index: lld/ELF/InputSection.cpp =================================================================== --- lld/ELF/InputSection.cpp +++ lld/ELF/InputSection.cpp @@ -854,7 +854,7 @@ unsigned RelI = 0; for (size_t Off = 0, End = Data.size(); Off != End;) { size_t Size = readEhRecordSize(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; Index: lld/ELF/MarkLive.cpp =================================================================== --- lld/ELF/MarkLive.cpp +++ lld/ELF/MarkLive.cpp @@ -126,7 +126,7 @@ unsigned FirstRelI = Piece.FirstRelocation; if (FirstRelI == (unsigned)-1) continue; - if (read32(Piece.data().data() + 4) == 0) { + if (read32(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(EH, Rels[FirstRelI], Fn); Index: lld/ELF/SyntheticSections.h =================================================================== --- lld/ELF/SyntheticSections.h +++ lld/ELF/SyntheticSections.h @@ -58,11 +58,6 @@ } }; -struct CieRecord { - EhSectionPiece *Piece = nullptr; - std::vector FdePieces; -}; - // Section for .eh_frame. template class EhFrameSection final : public SyntheticSection { typedef typename ELFT::Shdr Elf_Shdr; @@ -88,19 +83,27 @@ std::vector Sections; private: + struct CieRecord { + EhInputSection *Sec = nullptr; + EhSectionPiece *Cie = nullptr; + std::vector Fdes; + }; + uint64_t Size = 0; template void addSectionAux(EhInputSection *S, llvm::ArrayRef Rels); template - CieRecord *addCie(EhSectionPiece &Piece, ArrayRef Rels); + CieRecord *addCie(EhInputSection *Sec, EhSectionPiece &Piece, + ArrayRef Rels); template - bool isFdeLive(EhSectionPiece &Piece, ArrayRef Rels); + bool isFdeLive(EhInputSection *Sec, EhSectionPiece &Piece, + ArrayRef Rels); uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc); - std::vector Cies; + std::vector CieRecords; // CIE records are uniquified by their contents and personality functions. llvm::DenseMap, SymbolBody *>, CieRecord> CieMap; Index: lld/ELF/SyntheticSections.cpp =================================================================== --- lld/ELF/SyntheticSections.cpp +++ lld/ELF/SyntheticSections.cpp @@ -403,38 +403,38 @@ // and where their relocations point to. template template -CieRecord *EhFrameSection::addCie(EhSectionPiece &Piece, - ArrayRef Rels) { - auto *Sec = cast(Piece.Sec); +typename EhFrameSection::CieRecord * +EhFrameSection::addCie(EhInputSection *Sec, EhSectionPiece &Cie, + ArrayRef Rels) { const endianness E = ELFT::TargetEndianness; - if (read32(Piece.data().data() + 4) != 0) + if (read32(Cie.data(Sec).data() + 4) != 0) fatal(toString(Sec) + ": CIE expected at beginning of .eh_frame"); SymbolBody *Personality = nullptr; - unsigned FirstRelI = Piece.FirstRelocation; + unsigned FirstRelI = Cie.FirstRelocation; if (FirstRelI != (unsigned)-1) Personality = &Sec->template getFile()->getRelocTargetSym(Rels[FirstRelI]); // Search for an existing CIE by CIE contents/relocation target pair. - CieRecord *Cie = &CieMap[{Piece.data(), Personality}]; + CieRecord *Rec = &CieMap[{Cie.data(Sec), Personality}]; // If not found, create a new one. - if (Cie->Piece == nullptr) { - Cie->Piece = &Piece; - Cies.push_back(Cie); + if (Rec->Sec == nullptr) { + Rec->Sec = Sec; + Rec->Cie = &Cie; + CieRecords.push_back(Rec); } - return Cie; + return Rec; } // There is one FDE per function. Returns true if a given FDE // points to a live function. template template -bool EhFrameSection::isFdeLive(EhSectionPiece &Piece, +bool EhFrameSection::isFdeLive(EhInputSection *Sec, EhSectionPiece &Fde, ArrayRef Rels) { - auto *Sec = cast(Piece.Sec); - unsigned FirstRelI = Piece.FirstRelocation; + unsigned FirstRelI = Fde.FirstRelocation; // 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 @@ -469,20 +469,20 @@ return; size_t Offset = Piece.InputOff; - uint32_t ID = read32(Piece.data().data() + 4); + uint32_t ID = read32(Piece.data(Sec).data() + 4); if (ID == 0) { - OffsetToCie[Offset] = addCie(Piece, Rels); + OffsetToCie[Offset] = addCie(Sec, Piece, Rels); continue; } uint32_t CieOffset = Offset + 4 - ID; - CieRecord *Cie = OffsetToCie[CieOffset]; - if (!Cie) + CieRecord *Rec = OffsetToCie[CieOffset]; + if (!Rec) fatal(toString(Sec) + ": invalid CIE reference"); - if (!isFdeLive(Piece, Rels)) + if (!isFdeLive(Sec, Piece, Rels)) continue; - Cie->FdePieces.push_back(&Piece); + Rec->Fdes.push_back(&Piece); NumFdes++; } } @@ -532,11 +532,11 @@ return; // Already finalized. size_t Off = 0; - for (CieRecord *Cie : Cies) { - Cie->Piece->OutputOff = Off; - Off += alignTo(Cie->Piece->Size, Config->Wordsize); + for (CieRecord *Rec : CieRecords) { + Rec->Cie->OutputOff = Off; + Off += alignTo(Rec->Cie->Size, Config->Wordsize); - for (EhSectionPiece *Fde : Cie->FdePieces) { + for (EhSectionPiece *Fde : Rec->Fdes) { Fde->OutputOff = Off; Off += alignTo(Fde->Size, Config->Wordsize); } @@ -586,13 +586,13 @@ template void EhFrameSection::writeTo(uint8_t *Buf) { const endianness E = ELFT::TargetEndianness; - for (CieRecord *Cie : Cies) { - size_t CieOffset = Cie->Piece->OutputOff; - writeCieFde(Buf + CieOffset, Cie->Piece->data()); + for (CieRecord *Rec : CieRecords) { + size_t CieOffset = Rec->Cie->OutputOff; + writeCieFde(Buf + CieOffset, Rec->Cie->data(Rec->Sec)); - for (EhSectionPiece *Fde : Cie->FdePieces) { + for (EhSectionPiece *Fde : Rec->Fdes) { size_t Off = Fde->OutputOff; - writeCieFde(Buf + Off, Fde->data()); + writeCieFde(Buf + Off, Fde->data(Rec->Sec)); // FDE's second word should have the offset to an associated CIE. // Write it. @@ -607,9 +607,9 @@ // to get a FDE from an address to which FDE is applied. So here // we obtain two addresses and pass them to EhFrameHdr object. if (In::EhFrameHdr) { - for (CieRecord *Cie : Cies) { - uint8_t Enc = getFdeEncoding(Cie->Piece); - for (EhSectionPiece *Fde : Cie->FdePieces) { + for (CieRecord *Rec : CieRecords) { + uint8_t Enc = getFdeEncoding(Rec->Sec, Rec->Cie); + for (EhSectionPiece *Fde : Rec->Fdes) { uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc); uint64_t FdeVA = getParent()->Addr + Fde->OutputOff; In::EhFrameHdr->addFde(Pc, FdeVA);