diff options
-rw-r--r-- | lld/ELF/InputSection.cpp | 32 | ||||
-rw-r--r-- | lld/ELF/InputSection.h | 1 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 37 |
3 files changed, 34 insertions, 36 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 21dc8c21de5..513ccab2d23 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -407,6 +407,38 @@ bool EHInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) { return S->SectionKind == InputSectionBase<ELFT>::EHFrame; } +template <class ELFT> static size_t readRecordSize(ArrayRef<uint8_t> D) { + const endianness E = ELFT::TargetEndianness; + if (D.size() < 4) + fatal("CIE/FDE too small"); + + // First 4 bytes of CIE/FDE is the size of the record. + // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, + // but we do not support that format yet. + uint64_t V = read32<E>(D.data()); + if (V == UINT32_MAX) + fatal("CIE/FDE too large"); + uint64_t Size = V + 4; + if (Size > D.size()) + fatal("CIE/FIE ends past the end of the section"); + return Size; +} + +// .eh_frame is a sequence of CIE or FDE records. +// This function splits an input section into records and returns them. +template <class ELFT> +void EHInputSection<ELFT>::split() { + ArrayRef<uint8_t> Data = this->getSectionData(); + for (size_t Off = 0, End = Data.size(); Off != End;) { + size_t Size = readRecordSize<ELFT>(Data.slice(Off)); + // The empty record is the end marker. + if (Size == 4) + break; + this->Pieces.emplace_back(Off, Data.slice(Off, Size)); + Off += Size; + } +} + template <class ELFT> typename ELFT::uint EHInputSection<ELFT>::getOffset(uintX_t Offset) { // The file crtbeginT.o has relocations pointing to the start of an empty diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 6b2ea4babdd..bb089d55aeb 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -183,6 +183,7 @@ public: typedef typename ELFT::uint uintX_t; EHInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); static bool classof(const InputSectionBase<ELFT> *S); + void split(); // Translate an offset in the input section to an offset in the output // section. diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index a23803c8b39..a8d7088868c 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1072,23 +1072,6 @@ uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) { return DW_EH_PE_absptr; } -template <class ELFT> static size_t readRecordSize(ArrayRef<uint8_t> D) { - const endianness E = ELFT::TargetEndianness; - if (D.size() < 4) - fatal("CIE/FDE too small"); - - // First 4 bytes of CIE/FDE is the size of the record. - // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, - // but we do not support that format yet. - uint64_t V = read32<E>(D.data()); - if (V == UINT32_MAX) - fatal("CIE/FDE too large"); - uint64_t Size = V + 4; - if (Size > D.size()) - fatal("CIE/FIE ends past the end of the section"); - return Size; -} - // Returns the first relocation that points to a region // between Begin and Begin+Size. template <class IntTy, class RelTy> @@ -1102,24 +1085,6 @@ static const RelTy *getReloc(IntTy Begin, IntTy Size, ArrayRef<RelTy> Rels) { return &Rels[I]; } -// .eh_frame is a sequence of CIE or FDE records. -// This function splits an input section into records and returns them. -template <class ELFT> -std::vector<SectionPiece> -EHOutputSection<ELFT>::splitInputSection(const EHInputSection<ELFT> *Sec) { - ArrayRef<uint8_t> Data = Sec->getSectionData(); - std::vector<SectionPiece> V; - for (size_t Off = 0, End = Data.size(); Off != End;) { - size_t Size = readRecordSize<ELFT>(Data.slice(Off)); - // The empty record is the end marker. - if (Size == 4) - break; - V.emplace_back(Off, Data.slice(Off, Size)); - Off += Size; - } - return V; -} - // Search for an existing CIE record or create a new one. // CIE records from input object files are uniquified by their contents // and where their relocations point to. @@ -1206,7 +1171,7 @@ void EHOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { // .eh_frame is a sequence of CIE or FDE records. This function // splits it into pieces so that we can call // SplitInputSection::getSectionPiece on the section. - Sec->Pieces = splitInputSection(Sec); + Sec->split(); if (Sec->Pieces.empty()) return; |