From ff291b5833d17dfbbfa0581407c1ae1972315fbf Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Wed, 27 Jan 2016 14:05:35 +0000 Subject: [PATCH] [DebugInfo] Support zero-length CIE in the _eh_frame parser MCJIT emits zero-length CIE at the end of the _eh_frame section. This change ensures that parser inside DebugInfo will not crash and correctly record such cases. We are now recording DW_EH_PE_omit as a default value for FDE and LSDA encodings. Also Offset != EndAugmentationOffset assertion check will only happen if augmentation string had 'z' letter in it. Differential Revision: http://reviews.llvm.org/D16588 llvm-svn: 258931 --- llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 57 +++++++++--------- .../llvm-objdump/Inputs/eh_frame_zero_cie.o | Bin 0 -> 456 bytes .../tools/llvm-objdump/eh_frame_zero_cie.test | 10 +++ 3 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/Inputs/eh_frame_zero_cie.o create mode 100644 llvm/test/tools/llvm-objdump/eh_frame_zero_cie.test diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index 366fad411a9a..3f8ed43151c4 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -201,8 +201,8 @@ public: SmallString<8> Augmentation, uint8_t AddressSize, uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister, - SmallString<8> AugmentationData, Optional FDEPointerEncoding, - Optional LSDAPointerEncoding) + SmallString<8> AugmentationData, uint32_t FDEPointerEncoding, + uint32_t LSDAPointerEncoding) : FrameEntry(FK_CIE, Offset, Length), Version(Version), Augmentation(std::move(Augmentation)), AddressSize(AddressSize), @@ -219,10 +219,10 @@ public: StringRef getAugmentationString() const { return Augmentation; } uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; } int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; } - Optional getFDEPointerEncoding() const { + uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; } - Optional getLSDAPointerEncoding() const { + uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; } @@ -265,8 +265,8 @@ private: // The following are used when the CIE represents an EH frame entry. SmallString<8> AugmentationData; - Optional FDEPointerEncoding; - Optional LSDAPointerEncoding; + uint32_t FDEPointerEncoding; + uint32_t LSDAPointerEncoding; }; @@ -556,16 +556,16 @@ void DWARFDebugFrame::parse(DataExtractor Data) { uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); // Parse the augmentation data for EH CIEs - StringRef AugmentationData; - Optional FDEPointerEncoding; - Optional LSDAPointerEncoding; + StringRef AugmentationData(""); + uint32_t FDEPointerEncoding = DW_EH_PE_omit; + uint32_t LSDAPointerEncoding = DW_EH_PE_omit; if (IsEH) { Optional PersonalityEncoding; Optional Personality; - uint64_t AugmentationLength = 0; - uint32_t StartAugmentationOffset = 0; - uint32_t EndAugmentationOffset = 0; + Optional AugmentationLength; + uint32_t StartAugmentationOffset; + uint32_t EndAugmentationOffset; // Walk the augmentation string to get all the augmentation data. for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) { @@ -573,8 +573,6 @@ void DWARFDebugFrame::parse(DataExtractor Data) { default: ReportError("Unknown augmentation character in entry at %lx"); case 'L': - if (LSDAPointerEncoding) - ReportError("Duplicate LSDA encoding in entry at %lx"); LSDAPointerEncoding = Data.getU8(&Offset); break; case 'P': { @@ -585,8 +583,6 @@ void DWARFDebugFrame::parse(DataExtractor Data) { break; } case 'R': - if (FDEPointerEncoding) - ReportError("Duplicate FDE encoding in entry at %lx"); FDEPointerEncoding = Data.getU8(&Offset); break; case 'z': @@ -596,20 +592,22 @@ void DWARFDebugFrame::parse(DataExtractor Data) { // the string contains a 'z'. AugmentationLength = Data.getULEB128(&Offset); StartAugmentationOffset = Offset; - EndAugmentationOffset = - Offset + static_cast(AugmentationLength); + EndAugmentationOffset = Offset + + static_cast(*AugmentationLength); } } - if (Offset != EndAugmentationOffset) - ReportError("Parsing augmentation data at %lx failed"); + if (AugmentationLength.hasValue()) { + if (Offset != EndAugmentationOffset) + ReportError("Parsing augmentation data at %lx failed"); - AugmentationData = Data.getData().slice(StartAugmentationOffset, - EndAugmentationOffset); + AugmentationData = Data.getData().slice(StartAugmentationOffset, + EndAugmentationOffset); + } } auto Cie = make_unique(StartOffset, Length, Version, - StringRef(Augmentation), AddressSize, + AugmentationString, AddressSize, SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor, ReturnAddressRegister, AugmentationData, FDEPointerEncoding, @@ -628,12 +626,11 @@ void DWARFDebugFrame::parse(DataExtractor Data) { if (!Cie) ReportError("Parsing FDE data at %lx failed due to missing CIE"); - Optional FDEPointerEncoding = Cie->getFDEPointerEncoding(); - if (!FDEPointerEncoding) - ReportError("Parsing at %lx failed due to missing pointer encoding"); + InitialLocation = readPointer(Data, Offset, + Cie->getFDEPointerEncoding()); + AddressRange = readPointer(Data, Offset, + Cie->getFDEPointerEncoding()); - InitialLocation = readPointer(Data, Offset, *FDEPointerEncoding); - AddressRange = readPointer(Data, Offset, *FDEPointerEncoding); StringRef AugmentationString = Cie->getAugmentationString(); if (!AugmentationString.empty()) { // Parse the augmentation length and data for this FDE. @@ -644,8 +641,8 @@ void DWARFDebugFrame::parse(DataExtractor Data) { // Decode the LSDA if the CIE augmentation string said we should. uint64_t LSDA = 0; - if (Optional Encoding = Cie->getLSDAPointerEncoding()) - LSDA = readPointer(Data, Offset, *Encoding); + if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) + LSDA = readPointer(Data, Offset, Cie->getLSDAPointerEncoding()); if (Offset != EndAugmentationOffset) ReportError("Parsing augmentation data at %lx failed"); diff --git a/llvm/test/tools/llvm-objdump/Inputs/eh_frame_zero_cie.o b/llvm/test/tools/llvm-objdump/Inputs/eh_frame_zero_cie.o new file mode 100644 index 0000000000000000000000000000000000000000..ce159ad52f412240516bd084e4d331e6d484fa5e GIT binary patch literal 456 zcmb<-^>JfjWMqH=Mg}_u1P><4z|etUGB|+Q4h*bVRU#<_G4)DPD@qvjQZwSyiV|~E z8T5)vib@ibfOKUph^7({1e(K)#jFIVm?D}Sx*tJ&5N1PD=YYnCaamvtD9sL}f%*%W g(8L{}e025b_DcfQq3Z={^?>S^fYLB`a-fL=05xO}y8r+H literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-objdump/eh_frame_zero_cie.test b/llvm/test/tools/llvm-objdump/eh_frame_zero_cie.test new file mode 100644 index 000000000000..7b345c9d55a9 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/eh_frame_zero_cie.test @@ -0,0 +1,10 @@ +# RUN: llvm-objdump -dwarf=frames %p/Inputs/eh_frame_zero_cie.o 2>/dev/null | FileCheck %s + +# CHECK: .eh_frame contents: + +# CHECK: 00000000 00000000 ffffffff CIE +# CHECK: Version: 0 +# CHECK: Augmentation: "" +# CHECK: Code alignment factor: 0 +# CHECK: Data alignment factor: 0 +# CHECK: Return address column: 0