Skip to content

Commit

Permalink
[DebugInfo] Fix printing CIE offsets in EH FDEs.
Browse files Browse the repository at this point in the history
While the value of the CIE pointer field in a DWARF FDE record is
an offset to the corresponding CIE record from the beginning of
the section, for EH FDE records it is relative to the current offset.
Previously, we did not make that distinction when dumped both kinds
of FDE records and just printed the same value for the CIE pointer
field and the CIE offset; that was acceptable for DWARF FDEs but was
wrong for EH FDEs.

This patch fixes the issue by explicitly printing the offset of the
linked CIE object.

Differential Revision: https://reviews.llvm.org/D74613
  • Loading branch information
igorkudrin committed Feb 25, 2020
1 parent dcd89b3 commit bd2df13
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lld/test/ELF/eh-frame-hdr-augmentation.s
Expand Up @@ -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:
Expand Down
11 changes: 7 additions & 4 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
Expand Up @@ -223,14 +223,14 @@ class CIE : public FrameEntry {
/// 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<uint64_t> 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;
Expand All @@ -246,8 +246,11 @@ class FDE : public FrameEntry {
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;
Expand Down
12 changes: 8 additions & 4 deletions llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
Expand Up @@ -313,10 +313,14 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
}

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 << "<invalid offset>";
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);
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/RISCV/eh-frame.s
Expand Up @@ -28,7 +28,7 @@ func:
# 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:
14 changes: 14 additions & 0 deletions 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=<invalid offset> 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:
6 changes: 3 additions & 3 deletions llvm/test/MC/Mips/eh-frame.s
Expand Up @@ -67,7 +67,7 @@ func:
// 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:
Expand All @@ -89,8 +89,8 @@ func:
// 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:
Expand Up @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test
Expand Up @@ -8,7 +8,7 @@ CHECK-NOT: pc
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
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-objdump/eh_frame-arm64.test
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-objdump/eh_frame-coff.test
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-objdump/eh_frame-mipsel.test
Expand Up @@ -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
Expand Down

0 comments on commit bd2df13

Please sign in to comment.