[lld] 04b1dad - [lld-macho] Canonicalize LSDA pointers

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 5 13:19:41 PST 2022


Author: Jez Ng
Date: 2022-12-05T16:18:15-05:00
New Revision: 04b1dad7177be64fbe7a9e8f3477a4e2d8614da9

URL: https://github.com/llvm/llvm-project/commit/04b1dad7177be64fbe7a9e8f3477a4e2d8614da9
DIFF: https://github.com/llvm/llvm-project/commit/04b1dad7177be64fbe7a9e8f3477a4e2d8614da9.diff

LOG: [lld-macho] Canonicalize LSDA pointers

This was causing an uncaught exception issue in one of our programs. The
issue was fairly subtle / rare as it required two identical LSDAs that were
referenced by a pair of non-identical compact unwind encodings.

Reviewed By: #lld-macho, smeenai

Differential Revision: https://reviews.llvm.org/D139269

Added: 
    lld/test/MachO/icf-only-lsda-folded.s

Modified: 
    lld/MachO/UnwindInfoSection.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index 0e215f4712f42..470f33523ddb0 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -251,6 +251,11 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) {
   for (size_t i = 0; i < isec->relocs.size(); ++i) {
     Reloc &r = isec->relocs[i];
     assert(target->hasAttr(r.type, RelocAttrBits::UNSIGNED));
+    // Since compact unwind sections aren't part of the inputSections vector,
+    // they don't get canonicalized by scanRelocations(), so we have to do the
+    // canonicalization here.
+    if (auto *referentIsec = r.referent.dyn_cast<InputSection *>())
+      r.referent = referentIsec->canonical();
 
     // Functions and LSDA entries always reside in the same object file as the
     // compact unwind entries that references them, and thus appear as section

diff  --git a/lld/test/MachO/icf-only-lsda-folded.s b/lld/test/MachO/icf-only-lsda-folded.s
new file mode 100644
index 0000000000000..81cbe9955131d
--- /dev/null
+++ b/lld/test/MachO/icf-only-lsda-folded.s
@@ -0,0 +1,65 @@
+# REQUIRES: x86
+# RUN: rm -rf %t; split-file %s %t
+
+## This is a regression test. Previously, we would emit a bogus LSDA pointer if
+## the following conditions held:
+##   * ICF and dead-strip were both done
+##   * There exist two functions 
diff erent compact unwind encodings, but the
+##     same LSDA
+##
+## Essentially, we'd neglected to canonicalize the LSDA pointer after ICF, but
+## the broken output would only appear if the compact unwind entry that pointed
+## to it was not itself folded.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/test.s -o %t/test.o
+# RUN: %lld -dylib -dead_strip --icf=all %t/test.o -o %t/test
+# RUN: llvm-objdump --macho --syms --unwind-info %t/test | FileCheck %s
+
+# CHECK:      SYMBOL TABLE:
+## Sanity check: Verify that the LSDAs are dedup'ed
+# CHECK-NEXT: [[#%.16x, EXC:]]       l     O __TEXT,__gcc_except_tab _exception0
+# CHECK-NEXT: [[#EXC]]               l     O __TEXT,__gcc_except_tab _exception1
+## But that the functions themselves aren't
+# CHECK-NEXT: [[#%.16x, FOO:]]        g     F __TEXT,__text _foo
+# CHECK-NEXT: [[#%.16x, BAR:FOO + 1]] g     F __TEXT,__text _bar
+
+## _foo and _bar should share the same LSDA. We would previously emit a bogus
+## address for _bar's LSDA.
+# CHECK:      Contents of __unwind_info section:
+# CHECK:      LSDA descriptors:
+# CHECK-NEXT:     [0]: function offset=0x[[#%.8x, FOO]], LSDA offset=0x[[#%.8x, EXC]]
+# CHECK-NEXT:     [1]: function offset=0x[[#%.8x, BAR]], LSDA offset=0x[[#%.8x, EXC]]
+
+## But there should be two distinct encodings, one for each function
+# CHECK:      Second level indices:
+# CHECK-NEXT:     Second level index[0]:
+# CHECK-NEXT:       [0]: function offset=0x[[#%.8x, FOO]], encoding[0]=0x42020000
+# CHECK-NEXT:       [1]: function offset=0x[[#%.8x, BAR]], encoding[1]=0x42010000
+
+#--- test.s
+.text
+.globl _foo, _bar
+
+_foo:
+  .cfi_startproc
+	.cfi_lsda 16, _exception0
+	.cfi_def_cfa_offset 16
+  ret
+  .cfi_endproc
+
+_bar:
+  .cfi_startproc
+	.cfi_lsda 16, _exception1
+	.cfi_def_cfa_offset 8 ## ensure _bar's CUE doesn't get folded with _foo's
+  ret
+  .cfi_endproc
+
+.section	__TEXT,__gcc_except_tab
+
+_exception0:
+  .quad 0x1234
+
+_exception1:
+  .quad 0x1234
+
+.subsections_via_symbols


        


More information about the llvm-commits mailing list