[lld] [lld-macho] Ignore symbols in empty sections for unwind info (PR #225055)

marc hoffman via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 03:10:54 PDT 2026


https://github.com/dwarfland created https://github.com/llvm/llvm-project/pull/225055

See https://github.com/llvm/llvm-project/issues/224949.

>From 8e20b08f7adac437163b761f5fceb9a7ae2353d1 Mon Sep 17 00:00:00 2001
From: marc hoffman <mh at remobjects.com>
Date: Mon, 21 Sep 2026 06:06:18 -0400
Subject: [PATCH] [lld-macho] Ignore symbols in empty sections for unwind info

---
 lld/MachO/UnwindInfoSection.cpp               |  6 ++
 lld/test/MachO/compact-unwind-empty-section.s | 59 +++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 lld/test/MachO/compact-unwind-empty-section.s

diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index c8058b2df22a6..efec7abb125aa 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -183,6 +183,12 @@ UnwindInfoSection::UnwindInfoSection()
 // function symbols for each unique address regardless of whether they have
 // associated unwind info.
 void UnwindInfoSection::addSymbol(const Defined *d) {
+  // Empty input sections cover no address range and may have the same output
+  // address as the next function. Do not let their symbols create a conflicting
+  // no-unwind entry for that function.
+  if (d->isec()->getSize() == 0)
+    return;
+
   if (d->unwindEntry())
     allEntriesAreOmitted = false;
   // We don't yet know the final output address of this symbol, but we know that
diff --git a/lld/test/MachO/compact-unwind-empty-section.s b/lld/test/MachO/compact-unwind-empty-section.s
new file mode 100644
index 0000000000000..d1b962451dda9
--- /dev/null
+++ b/lld/test/MachO/compact-unwind-empty-section.s
@@ -0,0 +1,59 @@
+# REQUIRES: aarch64, x86
+# RUN: rm -rf %t; split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11 %t/empty.s -o %t/empty-arm64.o
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11 %t/code.s -o %t/code-arm64.o
+# RUN: %lld -arch arm64 -dylib %t/empty-arm64.o %t/code-arm64.o -o %t/arm64.dylib
+# RUN: llvm-objdump --macho --syms --unwind-info %t/arm64.dylib | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11 %t/empty.s -o %t/empty-x86_64.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11 %t/code.s -o %t/code-x86_64.o
+# RUN: %lld -dylib %t/empty-x86_64.o %t/code-x86_64.o -o %t/x86_64.dylib
+# RUN: llvm-objdump --macho --syms --unwind-info %t/x86_64.dylib | FileCheck %s
+
+## An empty input code section has the same output address as the following
+## function. Its local symbol must not add a conflicting no-unwind entry there.
+## A real function without unwind information must still get a zero entry.
+## The alias also checks that same-address symbols in nonempty sections work.
+
+# CHECK: SYMBOL TABLE:
+# CHECK-DAG: [[#%x,FIRST:]] g F __TEXT,__text _first
+# CHECK-DAG: [[#%x,FIRST]] g F __TEXT,__text _first_alias
+# CHECK-DAG: [[#%x,NO_UNWIND:]] g F __TEXT,__text _no_unwind
+# CHECK-DAG: [[#%x,LAST:]] g F __TEXT,__text _last
+# CHECK: Second level indices:
+# CHECK-NEXT: Second level index[0]:
+# CHECK-NEXT: [0]: function offset=0x[[#%.8x,FIRST]], encoding{{.*}}=0x02000000
+# CHECK-NEXT: [1]: function offset=0x[[#%.8x,NO_UNWIND]], encoding{{.*}}=0x00000000
+# CHECK-NEXT: [2]: function offset=0x[[#%.8x,LAST]], encoding{{.*}}=0x02000000
+# CHECK-NOT: function offset=
+
+#--- empty.s
+.section __TEXT,__text,regular,pure_instructions
+l_empty:
+.subsections_via_symbols
+
+#--- code.s
+.text
+.globl _first, _first_alias, _no_unwind, _last
+_first:
+_first_alias:
+  ret
+_no_unwind:
+  ret
+_last:
+  ret
+Llast_end:
+
+## Hand-written records make the unwind encodings identical on both targets.
+.section __LD,__compact_unwind,regular,debug
+.p2align 3
+.quad _first
+.long _no_unwind - _first
+.long 0x02000000
+.quad 0
+.quad 0
+.quad _last
+.long Llast_end - _last
+.long 0x02000000
+.quad 0
+.quad 0
+.subsections_via_symbols



More information about the llvm-commits mailing list