From 014b0f24aec951bf0e20d86cc43ab2e9ee9360e0 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 19 Sep 2017 23:36:48 +0000 Subject: [PATCH] Compact EhSectionPiece from 32 bytes to 16 bytes. EhSectionPiece used to have a pointer to a section, but that pointer was mostly redundant because we almost always know what the section is without using that pointer. This patch removes the pointer from the struct. This patch also use uint32_t/int32_t instead of size_t to represent offsets that are hardly be larger than 4 GiB. At the moment, I think it is OK even if we cannot handle .eh_frame sections larger than 4 GiB. Differential Revision: https://reviews.llvm.org/D38012 llvm-svn: 313697 --- lld/ELF/EhFrame.cpp | 17 +++++++++++------ lld/ELF/EhFrame.h | 4 +++- lld/ELF/InputSection.cpp | 2 +- lld/ELF/InputSection.h | 22 +++++++++++++--------- lld/ELF/MarkLive.cpp | 2 +- lld/ELF/SyntheticSections.cpp | 26 +++++++++++++------------- 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 e29110c..b0b141f 100644 --- a/lld/ELF/EhFrame.cpp +++ b/lld/ELF/EhFrame.cpp @@ -153,8 +153,9 @@ template void EhReader::skipAugP() { 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 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 *); diff --git a/lld/ELF/EhFrame.h b/lld/ELF/EhFrame.h index 07d1aaa..f33dab1 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 size_t readEhRecordSize(InputSectionBase *S, size_t Off); -template uint8_t getFdeEncoding(EhSectionPiece *P); +template +uint8_t getFdeEncoding(EhInputSection *, EhSectionPiece *); } // namespace elf } // namespace lld diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 016234a..0cf4b21 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -870,7 +870,7 @@ void EhInputSection::split(ArrayRef Rels) { 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; diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 15436df..dd518e5 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 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 @@ public: 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 diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index f3438c8..da7a724 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -126,7 +126,7 @@ scanEhFrameSection(EhInputSection &EH, ArrayRef Rels, 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); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b13aa47..c7aa392 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -403,11 +403,11 @@ EhFrameSection::EhFrameSection() // 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 @@ CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, &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 @@ CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, // 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 @@ void EhFrameSection::addSectionAux(EhInputSection *Sec, 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 @@ void EhFrameSection::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 void EhFrameSection::writeTo(uint8_t *Buf) { 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 @@ template void EhFrameSection::writeTo(uint8_t *Buf) { // 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; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 3176679..b9c7945 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 Fdes; }; @@ -93,10 +94,12 @@ private: 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); -- 2.7.4