diff --git a/lld/test/ELF/eh-frame-hdr-augmentation.s b/lld/test/ELF/eh-frame-hdr-augmentation.s --- a/lld/test/ELF/eh-frame-hdr-augmentation.s +++ b/lld/test/ELF/eh-frame-hdr-augmentation.s @@ -19,7 +19,7 @@ // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: -// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00001014...00001014 +// CHECK: 00000020 00000014 00000024 FDE cie=00000000 pc=00001014...00001014 // CHECK-NEXT: LSDA Address: 000000000000100b // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -223,14 +223,14 @@ /// DWARF Frame Description Entry (FDE) class FDE : public FrameEntry { public: - FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, + FDE(uint64_t Offset, uint64_t Length, uint64_t CIEPointer, uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie, Optional LSDAAddress, Triple::ArchType Arch) : FrameEntry(FK_FDE, Offset, Length, Cie ? Cie->getCodeAlignmentFactor() : 0, Cie ? Cie->getDataAlignmentFactor() : 0, Arch), - LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation), + CIEPointer(CIEPointer), InitialLocation(InitialLocation), AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {} ~FDE() override = default; @@ -246,8 +246,11 @@ static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; } private: - /// The following fields are defined in section 6.4.1 of the DWARF standard v3 - const uint64_t LinkedCIEOffset; + /// The following fields are defined in section 6.4.1 of the DWARFv3 standard. + /// Note that CIE pointers in EH FDEs, unlike DWARF FDEs, contain relative + /// offsets to the linked CIEs. See the following link for more info: + /// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html + const uint64_t CIEPointer; const uint64_t InitialLocation; const uint64_t AddressRange; const CIE *LinkedCIE; 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 @@ -313,10 +313,14 @@ } void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { - OS << format("%08x %08x %08x FDE ", (uint32_t)Offset, (uint32_t)Length, - (int32_t)LinkedCIEOffset); - OS << format("cie=%08x pc=%08x...%08x\n", (int32_t)LinkedCIEOffset, - (uint32_t)InitialLocation, + OS << format("%08x %08x %08x", (uint32_t)Offset, (uint32_t)Length, + (uint32_t)CIEPointer) + << " FDE cie="; + if (LinkedCIE) + OS << format("%08x", (uint32_t)(LinkedCIE->getOffset())); + else + OS << ""; + OS << format(" pc=%08x...%08x\n", (uint32_t)InitialLocation, (uint32_t)InitialLocation + (uint32_t)AddressRange); if (LSDAAddress) OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); diff --git a/llvm/test/DebugInfo/RISCV/eh-frame.s b/llvm/test/DebugInfo/RISCV/eh-frame.s --- a/llvm/test/DebugInfo/RISCV/eh-frame.s +++ b/llvm/test/DebugInfo/RISCV/eh-frame.s @@ -28,7 +28,7 @@ # CHECK: Augmentation data: 1B # CHECK: DW_CFA_def_cfa: reg2 +0 # -# CHECK: 00000014 00000010 00000018 FDE cie=00000018 pc=00000000...00000004 +# CHECK: 00000014 00000010 00000018 FDE cie=00000000 pc=00000000...00000004 # CHECK: DW_CFA_nop: # CHECK: DW_CFA_nop: # CHECK: DW_CFA_nop: diff --git a/llvm/test/DebugInfo/X86/debug_frame-invalid-cie-offset.s b/llvm/test/DebugInfo/X86/debug_frame-invalid-cie-offset.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/debug_frame-invalid-cie-offset.s @@ -0,0 +1,14 @@ +# RUN: llvm-mc -triple i386-unknown-linux %s -filetype=obj -o - | \ +# RUN: llvm-dwarfdump -debug-frame - | \ +# RUN: FileCheck %s + +# CHECK: .debug_frame contents: +# CHECK: 00000000 0000000c 12345678 FDE cie= pc=00010000...00010010 + + .section .debug_frame,"",@progbits + .long .LFDE0end-.LFDE0id # Length +.LFDE0id: + .long 0x12345678 # CIE pointer (invalid) + .long 0x00010000 # Initial location + .long 0x00000010 # Address range +.LFDE0end: diff --git a/llvm/test/MC/Mips/eh-frame.s b/llvm/test/MC/Mips/eh-frame.s --- a/llvm/test/MC/Mips/eh-frame.s +++ b/llvm/test/MC/Mips/eh-frame.s @@ -67,7 +67,7 @@ // DWARF32-EMPTY: // DWARF32-NEXT: DW_CFA_def_cfa_register: reg29 // -// DWARF32: 00000014 00000010 00000018 FDE cie=00000018 pc=00000000...00000000 +// DWARF32: 00000014 00000010 00000018 FDE cie=00000000 pc=00000000...00000000 // DWARF32-NEXT: DW_CFA_nop: // DWARF32-NEXT: DW_CFA_nop: // DWARF32-NEXT: DW_CFA_nop: @@ -89,8 +89,8 @@ // DWARF64-NEXT: DW_CFA_def_cfa_register: reg29 // DWARF64_PIC-NEXT: DW_CFA_nop: // -// DWARF64_ABS: 00000014 00000018 00000018 FDE cie=00000018 pc=00000000...00000000 -// DWARF64_PIC: 00000014 00000010 00000018 FDE cie=00000018 pc=00000000...00000000 +// DWARF64_ABS: 00000014 00000018 00000018 FDE cie=00000000 pc=00000000...00000000 +// DWARF64_PIC: 00000014 00000010 00000018 FDE cie=00000000 pc=00000000...00000000 // DWARF64-NEXT: DW_CFA_nop: // DWARF64-NEXT: DW_CFA_nop: // DWARF64-NEXT: DW_CFA_nop: diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_GNU_args_size.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_GNU_args_size.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_GNU_args_size.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_GNU_args_size.s @@ -2,7 +2,7 @@ # RUN: llvm-dwarfdump -v %t | FileCheck %s # CHECK: .eh_frame contents: -# CHECK: 00000018 00000010 0000001c FDE cie=0000001c pc=00000000...00000000 +# CHECK: 00000018 00000010 0000001c FDE cie=00000000 pc=00000000...00000000 # CHECK-NEXT: DW_CFA_GNU_args_size: +16 # CHECK-NEXT: DW_CFA_nop: diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test @@ -8,7 +8,7 @@ RUN: llvm-dwarfdump %p/../../dsymutil/Inputs/basic1.macho.x86_64.o \ RUN: -eh-frame=0x00000018 | FileCheck %s --check-prefix=EH EH: .eh_frame contents: -EH-NEXT: 00000018 00000024 0000001c FDE cie=0000001c pc=fffffd00...fffffd24 +EH-NEXT: 00000018 00000024 0000001c FDE cie=00000000 pc=fffffd00...fffffd24 EH-NEXT: DW_CFA_advance_loc: 1 EH-NOT: pc EH-NOT: CIE diff --git a/llvm/test/tools/llvm-objdump/eh_frame-arm64.test b/llvm/test/tools/llvm-objdump/eh_frame-arm64.test --- a/llvm/test/tools/llvm-objdump/eh_frame-arm64.test +++ b/llvm/test/tools/llvm-objdump/eh_frame-arm64.test @@ -12,7 +12,7 @@ # CHECK: DW_CFA_def_cfa: reg31 +0 -# CHECK: 00000014 00000020 00000018 FDE cie=00000018 pc=ffffffe4...00000004 +# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=ffffffe4...00000004 # CHECK: DW_CFA_advance_loc: 8 # CHECK: DW_CFA_def_cfa_offset: +16 # CHECK: DW_CFA_offset: reg30 -8 diff --git a/llvm/test/tools/llvm-objdump/eh_frame-coff.test b/llvm/test/tools/llvm-objdump/eh_frame-coff.test --- a/llvm/test/tools/llvm-objdump/eh_frame-coff.test +++ b/llvm/test/tools/llvm-objdump/eh_frame-coff.test @@ -16,7 +16,7 @@ # CHECK: DW_CFA_nop: # CHECK: DW_CFA_nop: -# CHECK: 00000020 0000001c 00000024 FDE cie=00000024 pc=00401410...00401488 +# CHECK: 00000020 0000001c 00000024 FDE cie=00000000 pc=00401410...00401488 # CHECK: LSDA Address: 0000000000406000 # CHECK: DW_CFA_advance_loc: 1 # CHECK: DW_CFA_def_cfa_offset: +8 diff --git a/llvm/test/tools/llvm-objdump/eh_frame-mipsel.test b/llvm/test/tools/llvm-objdump/eh_frame-mipsel.test --- a/llvm/test/tools/llvm-objdump/eh_frame-mipsel.test +++ b/llvm/test/tools/llvm-objdump/eh_frame-mipsel.test @@ -12,7 +12,7 @@ # CHECK: DW_CFA_def_cfa: reg29 +0 -# CHECK: 0000001c 00000018 00000020 FDE cie=00000020 pc=00400890...004008dc +# CHECK: 0000001c 00000018 00000020 FDE cie=00000000 pc=00400890...004008dc # CHECK: DW_CFA_advance_loc: 4 # CHECK: DW_CFA_def_cfa_offset: +24 # CHECK: DW_CFA_advance_loc: 4