From 754f1caff6088bc90b6b345146dc30bd6de50aaf Mon Sep 17 00:00:00 2001 From: Dan Blackwell Date: Tue, 18 Nov 2025 12:42:39 +0000 Subject: [PATCH 1/2] [AArch64] Force dwarf unwind for MTE-tagged stack frames Currently, running with -fsanitize=memtag-stack generates CompactUnwind exception unwinding that does not untag MTE-tagged memory on the way back up on Darwin. This patch forces dwarf unwinding on MTE-tagged frames. rdar://162195539 --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 7a2b6790f8a5b..1f9694cf98fec 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -586,6 +586,11 @@ class DarwinAArch64AsmBackend : public AArch64AsmBackend { /// Generate the compact unwind encoding from the CFI directives. uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const override { + // MTE-tagged frames must use DWARF unwinding because compact unwind + // doesn't handle MTE tags + if (FI->IsMTETaggedFrame) + return CU::UNWIND_ARM64_MODE_DWARF; + ArrayRef Instrs = FI->Instructions; if (Instrs.empty()) return CU::UNWIND_ARM64_MODE_FRAMELESS; From ec9dc47611e2d18e90c6226b5ac7f0d6596abfa9 Mon Sep 17 00:00:00 2001 From: Dan Blackwell Date: Wed, 19 Nov 2025 11:27:04 +0000 Subject: [PATCH 2/2] Add test --- .../CodeGen/AArch64/memtag-compact-unwind.ll | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/memtag-compact-unwind.ll diff --git a/llvm/test/CodeGen/AArch64/memtag-compact-unwind.ll b/llvm/test/CodeGen/AArch64/memtag-compact-unwind.ll new file mode 100644 index 0000000000000..50cda8d285a42 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/memtag-compact-unwind.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple=arm64-apple-macosx -mattr=+mte %s -filetype=obj -o %t.o +; RUN: llvm-objdump --unwind-info %t.o | FileCheck %s + +; Frames with MTE stack tagging must use DWARF unwinding because compact unwind +; doesn't handle MTE tag untagging during exception unwinding. + +; MTE-tagged frame should use DWARF mode (0x03000000) +; CHECK-LABEL: Contents of __compact_unwind section: +; CHECK: compact encoding: 0x03000000 + +; Normal frame should NOT use DWARF mode +; CHECK-NOT: compact encoding: 0x03000000 +; CHECK: compact encoding: 0x{{[0-9a-f]+}} + +define void @mte_tagged_frame() sanitize_memtag "frame-pointer"="all" { + %x = alloca i32, align 4 + store i32 42, ptr %x + call void asm sideeffect "", "r"(ptr %x) + ret void +} + +define void @normal_frame() "frame-pointer"="all" { + %x = alloca i32, align 4 + store i32 42, ptr %x + call void asm sideeffect "", "r"(ptr %x) + ret void +}