forked from OSchip/llvm-project
[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
This commit is contained in:
parent
7124c11ad9
commit
ff291b5833
|
@ -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");
|
||||
|
|
Binary file not shown.
|
@ -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
|
Loading…
Reference in New Issue