diff options
author | Igor Laevsky <igmyrj@gmail.com> | 2016-01-27 14:05:35 +0000 |
---|---|---|
committer | Igor Laevsky <igmyrj@gmail.com> | 2016-01-27 14:05:35 +0000 |
commit | ff291b5833d17dfbbfa0581407c1ae1972315fbf (patch) | |
tree | 2a968a19fb59b41f4013f0b58d7b38f25b9e2727 /llvm/lib/DebugInfo | |
parent | 7124c11ad9fef5b767aa94e4ac2c2d5e21c6381d (diff) | |
download | bcm5719-llvm-ff291b5833d17dfbbfa0581407c1ae1972315fbf.tar.gz bcm5719-llvm-ff291b5833d17dfbbfa0581407c1ae1972315fbf.zip |
[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
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index 366fad411a9..3f8ed43151c 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<uint32_t> FDEPointerEncoding, - Optional<uint32_t> 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<uint32_t> getFDEPointerEncoding() const { + uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; } - Optional<uint32_t> 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<uint32_t> FDEPointerEncoding; - Optional<uint32_t> 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<uint32_t> FDEPointerEncoding; - Optional<uint32_t> LSDAPointerEncoding; + StringRef AugmentationData(""); + uint32_t FDEPointerEncoding = DW_EH_PE_omit; + uint32_t LSDAPointerEncoding = DW_EH_PE_omit; if (IsEH) { Optional<uint32_t> PersonalityEncoding; Optional<uint64_t> Personality; - uint64_t AugmentationLength = 0; - uint32_t StartAugmentationOffset = 0; - uint32_t EndAugmentationOffset = 0; + Optional<uint64_t> 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<uint32_t>(AugmentationLength); + EndAugmentationOffset = Offset + + static_cast<uint32_t>(*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<CIE>(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<uint32_t> 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<uint32_t> 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"); |