https://github.com/jroelofs created https://github.com/llvm/llvm-project/pull/186458
Fixes libunwind's signal_frame.pass.cpp test on Mach-O platforms. >From 0df84bf18c4b77314922171540bf2d62ef955b80 Mon Sep 17 00:00:00 2001 From: Jon Roelofs <[email protected]> Date: Fri, 13 Mar 2026 09:15:20 -0700 Subject: [PATCH] [llvm][CompactUnwind] Compact unwind does not support .cfi_signal_frame Fixes libunwind's signal_frame.pass.cpp test on Mach-O platforms. --- libunwind/test/signal_frame.pass.cpp | 3 -- .../MCTargetDesc/AArch64AsmBackend.cpp | 4 +++ .../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 7 ++++ .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../arm64-compact-unwind-signal-frame.s | 33 +++++++++++++++++++ .../test/MC/ARM/compact-unwind-signal-frame.s | 24 ++++++++++++++ .../test/MC/X86/compact-unwind-signal-frame.s | 23 +++++++++++++ 7 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 llvm/test/MC/AArch64/arm64-compact-unwind-signal-frame.s create mode 100644 llvm/test/MC/ARM/compact-unwind-signal-frame.s create mode 100644 llvm/test/MC/X86/compact-unwind-signal-frame.s diff --git a/libunwind/test/signal_frame.pass.cpp b/libunwind/test/signal_frame.pass.cpp index 004029cfe1e90..a4676b15dd942 100644 --- a/libunwind/test/signal_frame.pass.cpp +++ b/libunwind/test/signal_frame.pass.cpp @@ -9,9 +9,6 @@ // Ensure that functions marked as signal frames are reported as such. -// TODO: Investigate this failure on Apple -// XFAIL: target={{.+}}-apple-{{.+}} - // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 48213d4da5d9f..eece54692e18c 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -580,6 +580,10 @@ class DarwinAArch64AsmBackend : public AArch64AsmBackend { if (FI->IsMTETaggedFrame) return CU::UNWIND_ARM64_MODE_DWARF; + // Signal frames cannot be encoded in compact unwind. + if (FI->IsSignalFrame) + return CU::UNWIND_ARM64_MODE_DWARF; + ArrayRef<MCCFIInstruction> Instrs = FI->Instructions; if (Instrs.empty()) return CU::UNWIND_ARM64_MODE_FRAMELESS; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 243fa7b512d0d..28277ece97c91 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -1171,13 +1171,20 @@ enum CompactUnwindEncodings { uint64_t ARMAsmBackendDarwin::generateCompactUnwindEncoding( const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const { DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n"); + // Only armv7k uses CFI based unwinding. if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K) return 0; + + // Signal frames cannot be encoded in compact unwind. + if (FI->IsSignalFrame) + return CU::UNWIND_ARM_MODE_DWARF; + // No .cfi directives means no frame. ArrayRef<MCCFIInstruction> Instrs = FI->Instructions; if (Instrs.empty()) return 0; + if (!isDarwinCanonicalPersonality(FI->Personality) && !Ctxt->emitCompactUnwindNonCanonical()) return CU::UNWIND_ARM_MODE_DWARF; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 3a1d960304db0..7515c75ab33e1 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -1306,6 +1306,10 @@ class DarwinX86AsmBackend : public X86AsmBackend { /// for the CFI instructions. uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const override { + // Signal frames cannot be encoded in compact unwind. + if (FI->IsSignalFrame) + return CU::UNWIND_MODE_DWARF; + ArrayRef<MCCFIInstruction> Instrs = FI->Instructions; if (Instrs.empty()) return 0; if (!isDarwinCanonicalPersonality(FI->Personality) && diff --git a/llvm/test/MC/AArch64/arm64-compact-unwind-signal-frame.s b/llvm/test/MC/AArch64/arm64-compact-unwind-signal-frame.s new file mode 100644 index 0000000000000..34b0e64a05b3d --- /dev/null +++ b/llvm/test/MC/AArch64/arm64-compact-unwind-signal-frame.s @@ -0,0 +1,33 @@ +// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj %s -o %t.o +// RUN: llvm-objdump --macho --unwind-info --dwarf=frames %t.o | FileCheck %s + +/// Signal frames cannot be encoded in compact unwind. Verify that +/// .cfi_signal_frame causes UNWIND_ARM64_MODE_DWARF (0x03000000) to be +/// emitted in the __compact_unwind section, and that the corresponding DWARF +/// CIE carries the 'S' augmentation character. A non-signal frame in the +/// same translation unit is encoded normally (UNWIND_ARM64_MODE_FRAMELESS, +/// 0x02000000) and needs no DWARF FDE. + + .globl _f +_f: + .cfi_startproc + .cfi_signal_frame + ret + .cfi_endproc + + .globl _g +_g: + .cfi_startproc + ret + .cfi_endproc + +// CHECK: Contents of __compact_unwind section: +// CHECK: Entry at offset 0x0: +// CHECK: compact encoding: 0x03000000 +// CHECK: Entry at offset 0x20: +// CHECK: start: 0x{{.*}} _g +// CHECK: compact encoding: 0x02000000 + +// CHECK: .eh_frame contents: +// CHECK: CIE +// CHECK: Augmentation: "zRS" diff --git a/llvm/test/MC/ARM/compact-unwind-signal-frame.s b/llvm/test/MC/ARM/compact-unwind-signal-frame.s new file mode 100644 index 0000000000000..55fb95f2cd2aa --- /dev/null +++ b/llvm/test/MC/ARM/compact-unwind-signal-frame.s @@ -0,0 +1,24 @@ +// RUN: llvm-mc -triple=armv7k-apple-ios -filetype=obj %s -o %t.o +// RUN: llvm-objdump --macho --unwind-info --dwarf=frames %t.o | FileCheck %s + +/// Signal frames cannot be encoded in compact unwind. Verify that +/// .cfi_signal_frame causes UNWIND_ARM_MODE_DWARF (0x04000000) to be emitted +/// in the __compact_unwind section, and that the corresponding DWARF CIE +/// carries the 'S' augmentation character. + + .globl _f +_f: + .cfi_startproc + .cfi_signal_frame + bx lr + .cfi_endproc + +// CHECK: Contents of __compact_unwind section: +// CHECK: Entry at offset 0x0: +// CHECK: start: 0x0 _f +// CHECK: length: 0x4 +// CHECK: compact encoding: 0x04000000 + +// CHECK: .eh_frame contents: +// CHECK: CIE +// CHECK: Augmentation: "zRS" diff --git a/llvm/test/MC/X86/compact-unwind-signal-frame.s b/llvm/test/MC/X86/compact-unwind-signal-frame.s new file mode 100644 index 0000000000000..a63f5389aea2f --- /dev/null +++ b/llvm/test/MC/X86/compact-unwind-signal-frame.s @@ -0,0 +1,23 @@ +// RUN: llvm-mc -triple x86_64-apple-macos10.6 -filetype=obj %s -o %t.o +// RUN: llvm-objdump --macho --unwind-info --dwarf=frames %t.o | FileCheck %s + +/// Signal frames cannot be encoded in compact unwind. Verify that +/// .cfi_signal_frame causes UNWIND_X86_MODE_DWARF (0x04000000) to be emitted +/// in the __compact_unwind section, and that the corresponding DWARF CIE +/// carries the 'S' augmentation character. + +_f: + .cfi_startproc + .cfi_signal_frame + ret + .cfi_endproc + +// CHECK: Contents of __compact_unwind section: +// CHECK: Entry at offset 0x0: +// CHECK: start: 0x0 _f +// CHECK: length: 0x1 +// CHECK: compact encoding: 0x04000000 + +// CHECK: .eh_frame contents: +// CHECK: CIE +// CHECK: Augmentation: "zRS" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
