[lld] 96d0875 - [lld-macho][objc] Don't crash when rodata isn't statically linked

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 30 11:33:54 PDT 2023


Author: Jez Ng
Date: 2023-03-30T14:33:43-04:00
New Revision: 96d087512ea7aa9e81b11665933a14854df96a89

URL: https://github.com/llvm/llvm-project/commit/96d087512ea7aa9e81b11665933a14854df96a89
DIFF: https://github.com/llvm/llvm-project/commit/96d087512ea7aa9e81b11665933a14854df96a89.diff

LOG: [lld-macho][objc] Don't crash when rodata isn't statically linked

We were previously assuming that to hold, but it appears that `swiftc`
may generate classes that link against `__objc_empty_cache` for their
rodata pointer.

This should allow us to re-land {D142916} (as a stack).

Reviewed By: #lld-macho, oontvoo

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

Added: 
    

Modified: 
    lld/MachO/ObjC.cpp
    lld/test/MachO/objc-category-conflicts.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index 18b1fafc49d6..dce75543fc2b 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -259,12 +259,14 @@ void ObjcCategoryChecker::parseClass(const Defined *classSym) {
   auto getMethodsIsec =
       [&](const InputSection *classIsec) -> ConcatInputSection * {
     if (const auto *r = classIsec->getRelocAt(classLayout.roDataOffset)) {
-      const auto *roIsec =
-          cast<ConcatInputSection>(r->getReferentInputSection());
-      if (const auto *r = roIsec->getRelocAt(roClassLayout.baseMethodsOffset)) {
-        if (auto *methodsIsec =
-                cast_or_null<ConcatInputSection>(r->getReferentInputSection()))
-          return methodsIsec;
+      if (const auto *roIsec =
+              cast_or_null<ConcatInputSection>(r->getReferentInputSection())) {
+        if (const auto *r =
+                roIsec->getRelocAt(roClassLayout.baseMethodsOffset)) {
+          if (auto *methodsIsec = cast_or_null<ConcatInputSection>(
+                  r->getReferentInputSection()))
+            return methodsIsec;
+        }
       }
     }
     return nullptr;

diff  --git a/lld/test/MachO/objc-category-conflicts.s b/lld/test/MachO/objc-category-conflicts.s
index c88783e751fd..546f042bc067 100644
--- a/lld/test/MachO/objc-category-conflicts.s
+++ b/lld/test/MachO/objc-category-conflicts.s
@@ -3,6 +3,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -o %t/cat1.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -o %t/cat2.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -o %t/klass.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass-with-no-rodata.s -o %t/klass-with-no-rodata.o
 # RUN: %lld -dylib -lobjc %t/klass.o -o %t/libklass.dylib
 
 # RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
@@ -10,6 +11,9 @@
 # RUN: %no-fatal-warnings-lld -dylib -lobjc %t/libklass.dylib %t/cat1.o \
 # RUN:   %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT
 
+## Regression test: Check that we don't crash.
+# RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass-with-no-rodata.o -o /dev/null
+
 # CATCLS:      warning: method '+s1' has conflicting definitions:
 # CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
 # CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass.o
@@ -199,6 +203,42 @@ __OBJC_$_INSTANCE_METHODS_Foo:
 
 .subsections_via_symbols
 
+#--- klass-with-no-rodata.s
+
+.include "objc-macros.s"
+
+## swiftc generates some classes without a statically-linked rodata. Not
+## entirely sure what the corresponding Swift inputs are required for this to
+## happen; this test merely checks that we can gracefully handle this case
+## without crashing.
+## FIXME: It would be better if this test used the output of some real Swift
+## code.
+
+.globl _$s11FooAACfD
+
+.section __DATA,__objc_data
+_$s11FooAACfD:
+  .quad _$s11FooAACfD
+  .quad 0
+  .quad __objc_empty_cache
+  .quad 0
+  .quad __objc_empty_cache
+
+.section __DATA,__objc_catlist,regular,no_dead_strip
+  .quad __CATEGORY_METAFoo_$_Foo20
+
+.section __DATA,__objc_const
+__CATEGORY_METAFoo_$_Foo20:
+  .objc_classname "Foo20"
+  .quad _$s11FooAACfD
+  .quad 0
+  .quad 0
+  .quad 0
+  .quad 0
+  .quad 0
+  .long 64
+  .space 4
+
 #--- objc-macros.s
 
 # Macros for taking some of the boilerplate out of defining objc structs.


        


More information about the llvm-commits mailing list