Index: lld/trunk/ELF/EhFrame.h =================================================================== --- lld/trunk/ELF/EhFrame.h +++ lld/trunk/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/trunk/ELF/EhFrame.cpp =================================================================== --- lld/trunk/ELF/EhFrame.cpp +++ lld/trunk/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/trunk/ELF/InputSection.h =================================================================== --- lld/trunk/ELF/InputSection.h +++ lld/trunk/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/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -870,7 +870,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/trunk/ELF/MarkLive.cpp =================================================================== --- lld/trunk/ELF/MarkLive.cpp +++ lld/trunk/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/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -59,6 +59,7 @@ }; struct CieRecord { + EhInputSection *Sec = nullptr; EhSectionPiece *Cie = nullptr; std::vector Fdes; }; @@ -93,10 +94,12 @@ 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); Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -403,11 +403,11 @@ // and where their relocations point to. template template -CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, +CieRecord *EhFrameSection::addCie(EhInputSection *Sec, + EhSectionPiece &Cie, ArrayRef Rels) { - auto *Sec = cast(Cie.Sec); const endianness E = ELFT::TargetEndianness; - if (read32(Cie.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; @@ -417,10 +417,11 @@ &Sec->template getFile()->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 @@ // points to a live function. template template -bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, +bool EhFrameSection::isFdeLive(EhInputSection *Sec, EhSectionPiece &Fde, ArrayRef Rels) { - auto *Sec = cast(Fde.Sec); unsigned FirstRelI = Fde.FirstRelocation; // An FDE should point to some function because FDEs are to describe @@ -469,9 +469,9 @@ 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; } @@ -480,7 +480,7 @@ 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 @@ const endianness E = ELFT::TargetEndianness; for (CieRecord *Rec : CieRecords) { size_t CieOffset = Rec->Cie->OutputOff; - writeCieFde(Buf + CieOffset, Rec->Cie->data()); + writeCieFde(Buf + CieOffset, Rec->Cie->data(Rec->Sec)); 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. @@ -606,7 +606,7 @@ // we obtain two addresses and pass them to EhFrameHdr object. if (In::EhFrameHdr) { for (CieRecord *Rec : CieRecords) { - uint8_t Enc = getFdeEncoding(Rec->Cie); + 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;