diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -285,6 +285,18 @@ } } +// Returns the CIE identifier to be used by the requested format. +// CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5. +// For CIE ID in .eh_frame sections see +// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html +constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) { + if (IsEH) + return 0; + if (IsDWARF64) + return DW64_CIE_ID; + return DW_CIE_ID; +} + void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { OS << format("%08x %08x %08x CIE", (uint32_t)Offset, (uint32_t)Length, IsEH ? 0 : DW_CIE_ID) @@ -379,10 +391,7 @@ // The Id field's size depends on the DWARF format bool IsDWARF64 = Format == DWARF64; Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset); - bool IsCIE = - ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID || (IsEH && !Id)); - - if (IsCIE) { + if (Id == getCIEId(IsDWARF64, IsEH)) { uint8_t Version = Data.getU8(&Offset); const char *Augmentation = Data.getCStr(&Offset); StringRef AugmentationString(Augmentation ? Augmentation : ""); diff --git a/llvm/test/DebugInfo/X86/debug-frame-cie-id-dwarf64.s b/llvm/test/DebugInfo/X86/debug-frame-cie-id-dwarf64.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/debug-frame-cie-id-dwarf64.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ +# RUN: llvm-dwarfdump -debug-frame - | \ +# RUN: FileCheck %s + +# CHECK: 00000000 {{.*}} FDE + + .section .debug_frame,"",@progbits +## This FDE was formerly wrongly interpreted as a CIE because its CIE pointer +## is similar to DWARF32 CIE id. + .long 0xffffffff # DWARF64 mark + .quad .Lend - .LCIEptr # Length +.LCIEptr: + .quad 0xffffffff # CIE pointer + .quad 0x1111abcd # Initial location + .quad 0x00010000 # Address range +.Lend: diff --git a/llvm/test/DebugInfo/X86/eh-frame-cie-id.s b/llvm/test/DebugInfo/X86/eh-frame-cie-id.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/eh-frame-cie-id.s @@ -0,0 +1,15 @@ +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ +# RUN: not --crash llvm-dwarfdump -debug-frame - 2>&1 | \ +# RUN: FileCheck %s + +# CHECK: Parsing FDE data at 0 failed due to missing CIE + + .section .eh_frame,"a",@unwind +## This FDE was formerly wrongly interpreted as a CIE because its CIE pointer +## is similar to CIE id of a .debug_frame FDE. + .long .Lend - .LCIEptr # Length +.LCIEptr: + .long 0xffffffff # CIE pointer + .quad 0x1111abcd # Initial location + .quad 0x00010000 # Address range +.Lend: