[lld] [lld-macho] Category merger: handle addends when getting symbol at offset (PR #91238)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 18:38:01 PDT 2024


https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/91238

>From 1d28d05f39308fad2cabc5ab63f8ed46a5708848 Mon Sep 17 00:00:00 2001
From: Alex Borcan <alexborcan at fb.com>
Date: Sun, 5 May 2024 19:40:10 -0700
Subject: [PATCH 1/2] [lld-macho]  Category merger: handle addends when getting
 symbol at isec offset

---
 lld/MachO/ObjC.cpp | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index 413fa0bb64390..ab4ea0d399601 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -490,6 +490,7 @@ class ObjcCategoryMerger {
   Defined *emitCategoryName(const std::string &name, ObjFile *objFile);
   void createSymbolReference(Defined *refFrom, const Symbol *refTo,
                              uint32_t offset, const Reloc &relocTemplate);
+  Defined *tryFindDefinedOnIsec(const InputSection *isec, uint32_t offset);
   Symbol *tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
                                    uint32_t offset);
   Defined *tryGetDefinedAtIsecOffset(const ConcatInputSection *isec,
@@ -566,7 +567,25 @@ ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
   if (!reloc)
     return nullptr;
 
-  return reloc->referent.get<Symbol *>();
+  Symbol *sym = reloc->referent.get<Symbol *>();
+
+  if (reloc->addend) {
+    assert(isa<Defined>(sym) && "Expected defined for non-zero addend");
+    Defined *definedSym = cast<Defined>(sym);
+    sym = tryFindDefinedOnIsec(definedSym->isec(),
+                               definedSym->value + reloc->addend);
+  }
+
+  return sym;
+}
+
+Defined *ObjcCategoryMerger::tryFindDefinedOnIsec(const InputSection *isec,
+                                                  uint32_t offset) {
+  for (Defined *sym : isec->symbols)
+    if ((sym->value <= offset) && (sym->value + sym->size > offset))
+      return sym;
+
+  return nullptr;
 }
 
 Defined *

>From 4798b9cda1cfc637312e411d45103493b1aaaa04 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Thu, 20 Jun 2024 16:52:57 -0700
Subject: [PATCH 2/2] Address feedback nr.1

---
 lld/MachO/ObjC.cpp                           |  10 +-
 lld/test/MachO/objc-category-merging-swift.s | 378 +++++++++++++++++++
 2 files changed, 386 insertions(+), 2 deletions(-)
 create mode 100644 lld/test/MachO/objc-category-merging-swift.s

diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index ab4ea0d399601..2033703f3caa2 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -574,6 +574,8 @@ ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
     Defined *definedSym = cast<Defined>(sym);
     sym = tryFindDefinedOnIsec(definedSym->isec(),
                                definedSym->value + reloc->addend);
+
+    auto *defSym = dyn_cast<Defined>(sym);
   }
 
   return sym;
@@ -1307,8 +1309,12 @@ void ObjcCategoryMerger::eraseMergedCategories() {
         continue;
 
       eraseISec(catInfo.catBodyIsec);
-
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
+      // We can't erase 'catLayout.nameOffset' for Swift categories because the
+      // name will be referenced for generating relative offsets
+      // See usages of 'l_.str.11.SimpleClass' in objc-category-merging-swift.s
+      // TODO: handle the above in a smarter way
+      if (catInfo.sourceLanguage != SourceLanguage::Swift)
+        tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
       tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
                                   catLayout.instanceMethodsOffset);
       tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
diff --git a/lld/test/MachO/objc-category-merging-swift.s b/lld/test/MachO/objc-category-merging-swift.s
new file mode 100644
index 0000000000000..acad35173c3a3
--- /dev/null
+++ b/lld/test/MachO/objc-category-merging-swift.s
@@ -0,0 +1,378 @@
+# REQUIRES: aarch64
+# RUN: rm -rf %t; mkdir %t && cd %t
+
+############ Test merging multiple categories into a single category ############
+## Create a dylib with a fake base class to link against in when merging between categories
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o cat_swift.o %s
+# RUN: %lld -arch arm64 -dylib -o cat_swift.dylib cat_swift.o -objc_category_merging --threads=1
+
+; #### Check merge categories enabled ###
+; # Check that the original categories are not there
+; MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
+; MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category0; 2
+
+; # Check that the merged cateogry is there, in the correct format
+; MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02)
+; MERGE_CATS-NEXT:   name {{.*}} Category01|Category02
+; MERGE_CATS:       instanceMethods
+; MERGE_CATS-NEXT:  24
+; MERGE_CATS-NEXT:  2
+; MERGE_CATS-NEXT:   name {{.*}} cat01_InstanceMethod
+; MERGE_CATS-NEXT:  types {{.*}} v16 at 0:8
+; MERGE_CATS-NEXT:    imp -[MyBaseClass(Category01) cat01_InstanceMethod]
+; MERGE_CATS-NEXT:   name {{.*}} cat02_InstanceMethod
+; MERGE_CATS-NEXT:  types {{.*}} v16 at 0:8
+; MERGE_CATS-NEXT:    imp -[MyBaseClass(Category02) cat02_InstanceMethod]
+; MERGE_CATS-NEXT:         classMethods 0x0
+; MERGE_CATS-NEXT:            protocols 0x0
+; MERGE_CATS-NEXT:   instanceProperties 0x0
+
+
+;  ================== Generated from Swift: ==================
+;; > xcrun swiftc -S SimpleClass.swift -o SimpleClass.s
+; import Foundation
+; @objc class SimpleClass: NSObject {
+;     @objc func baseClassInstanceMethod() -> Int32 {
+;         return 2
+;     }
+; }
+; extension SimpleClass {
+;     @objc func categoryInstanceMethod() -> Int {
+;         return 3
+;     }
+; }
+
+;  ================== Generated from Swift: ==================
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 11, 0	sdk_version 12, 0
+	.globl	_main
+	.p2align	2
+_main:
+	.cfi_startproc
+	mov	w0, #0
+	ret
+	.cfi_endproc
+
+	.private_extern	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyF
+	.globl	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyF
+	.p2align	2
+_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyF:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.p2align	2
+_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyFTo:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.private_extern	_$s11SimpleClassAACABycfC
+	.globl	_$s11SimpleClassAACABycfC
+	.p2align	2
+_$s11SimpleClassAACABycfC:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.private_extern	_$s11SimpleClassAACABycfc
+	.globl	_$s11SimpleClassAACABycfc
+	.p2align	2
+_$s11SimpleClassAACABycfc:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.private_extern	_$s11SimpleClassAACMa
+	.globl	_$s11SimpleClassAACMa
+	.p2align	2
+_$s11SimpleClassAACMa:
+	ret
+
+	.p2align	2
+_$s11SimpleClassAACABycfcTo:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.private_extern	_$s11SimpleClassAACfD
+	.globl	_$s11SimpleClassAACfD
+	.p2align	2
+_$s11SimpleClassAACfD:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.private_extern	_$s11SimpleClassAAC22categoryInstanceMethodSiyF
+	.globl	_$s11SimpleClassAAC22categoryInstanceMethodSiyF
+	.p2align	2
+_$s11SimpleClassAAC22categoryInstanceMethodSiyF:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.p2align	2
+_$s11SimpleClassAAC22categoryInstanceMethodSiyFTo:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+
+	.section	__TEXT,__objc_methname,cstring_literals
+"L_selector_data(init)":
+	.asciz	"init"
+
+	.section	__DATA,__objc_selrefs,literal_pointers,no_dead_strip
+	.p2align	3, 0x0
+"L_selector(init)":
+	.quad	"L_selector_data(init)"
+
+	.section	__TEXT,__objc_methname,cstring_literals
+"L_selector_data(dealloc)":
+	.asciz	"dealloc"
+
+	.section	__DATA,__objc_selrefs,literal_pointers,no_dead_strip
+	.p2align	3, 0x0
+"L_selector(dealloc)":
+	.quad	"L_selector_data(dealloc)"
+
+	.section	__TEXT,__swift5_entry,regular,no_dead_strip
+	.p2align	2, 0x0
+l_entry_point:
+	.long	_main-l_entry_point
+	.long	0
+
+	.private_extern	_OBJC_METACLASS_$__TtC11SimpleClass11SimpleClass
+	.section	__DATA,__data
+	.globl	_OBJC_METACLASS_$__TtC11SimpleClass11SimpleClass
+	.p2align	3, 0x0
+_OBJC_METACLASS_$__TtC11SimpleClass11SimpleClass:
+	.quad	_OBJC_METACLASS_$_NSObject
+	.quad	_OBJC_METACLASS_$_NSObject
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__METACLASS_DATA__TtC11SimpleClass11SimpleClass
+
+	.section	__TEXT,__cstring,cstring_literals
+	.p2align	4, 0x0
+l_.str.30._TtC11SimpleClass11SimpleClass:
+	.asciz	"_TtC11SimpleClass11SimpleClass"
+
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0
+__METACLASS_DATA__TtC11SimpleClass11SimpleClass:
+	.long	129
+	.long	40
+	.long	40
+	.long	0
+	.quad	0
+	.quad	l_.str.30._TtC11SimpleClass11SimpleClass
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.section	__TEXT,__objc_methname,cstring_literals
+"L_selector_data(baseClassInstanceMethod)":
+	.asciz	"baseClassInstanceMethod"
+
+	.section	__TEXT,__cstring,cstring_literals
+"l_.str.7.i16 at 0:8":
+	.asciz	"i16 at 0:8"
+
+"l_.str.7. at 16@0:8":
+	.asciz	"@16 at 0:8"
+
+	.section	__DATA,__objc_data
+	.p2align	3, 0x0
+__INSTANCE_METHODS__TtC11SimpleClass11SimpleClass:
+	.long	24
+	.long	2
+	.quad	"L_selector_data(baseClassInstanceMethod)"
+	.quad	"l_.str.7.i16 at 0:8"
+	.quad	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyFTo
+	.quad	"L_selector_data(init)"
+	.quad	"l_.str.7. at 16@0:8"
+	.quad	_$s11SimpleClassAACABycfcTo
+
+	.p2align	3, 0x0
+__DATA__TtC11SimpleClass11SimpleClass:
+	.long	128
+	.long	8
+	.long	8
+	.long	0
+	.quad	0
+	.quad	l_.str.30._TtC11SimpleClass11SimpleClass
+	.quad	__INSTANCE_METHODS__TtC11SimpleClass11SimpleClass
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.section	__TEXT,__const
+l_.str.11.SimpleClass:
+	.asciz	"SimpleClass"
+
+	.private_extern	_$s11SimpleClassMXM
+	.section	__TEXT,__constg_swiftt
+	.globl	_$s11SimpleClassMXM
+	.weak_definition	_$s11SimpleClassMXM
+	.p2align	2, 0x0
+_$s11SimpleClassMXM:
+	.long	0
+	.long	0
+	.long	(l_.str.11.SimpleClass-_$s11SimpleClassMXM)-8
+
+	.private_extern	"_symbolic So8NSObjectC"
+	.section	__TEXT,__swift5_typeref
+	.globl	"_symbolic So8NSObjectC"
+	.weak_definition	"_symbolic So8NSObjectC"
+	.p2align	1, 0x0
+"_symbolic So8NSObjectC":
+	.ascii	"So8NSObjectC"
+	.byte	0
+
+	.private_extern	_$s11SimpleClassAACMn
+	.section	__TEXT,__constg_swiftt
+	.globl	_$s11SimpleClassAACMn
+	.p2align	2, 0x0
+_$s11SimpleClassAACMn:
+	.long	2147483728
+	.long	(_$s11SimpleClassMXM-_$s11SimpleClassAACMn)-4
+	.long	(l_.str.11.SimpleClass-_$s11SimpleClassAACMn)-8
+	.long	(_$s11SimpleClassAACMa-_$s11SimpleClassAACMn)-12
+	.long	(_$s11SimpleClassAACMF-_$s11SimpleClassAACMn)-16
+	.long	("_symbolic So8NSObjectC"-_$s11SimpleClassAACMn)-20
+	.long	3
+	.long	11
+	.long	1
+	.long	0
+	.long	10
+	.long	10
+	.long	1
+	.long	16
+	.long	(_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyF-_$s11SimpleClassAACMn)-56
+
+	.section	__DATA,__objc_data
+	.p2align	3, 0x0
+_$s11SimpleClassAACMf:
+	.quad	0
+	.quad	_$s11SimpleClassAACfD
+	.quad	_$sBOWV
+	.quad	_OBJC_METACLASS_$__TtC11SimpleClass11SimpleClass
+	.quad	_OBJC_CLASS_$_NSObject
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__DATA__TtC11SimpleClass11SimpleClass+2
+	.long	0
+	.long	0
+	.long	8
+	.short	7
+	.short	0
+	.long	112
+	.long	24
+	.quad	_$s11SimpleClassAACMn
+	.quad	0
+	.quad	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyF
+
+	.private_extern	"_symbolic _____ 11SimpleClassAAC"
+	.section	__TEXT,__swift5_typeref
+	.globl	"_symbolic _____ 11SimpleClassAAC"
+	.weak_definition	"_symbolic _____ 11SimpleClassAAC"
+	.p2align	1, 0x0
+"_symbolic _____ 11SimpleClassAAC":
+	.byte	1
+	.long	(_$s11SimpleClassAACMn-"_symbolic _____ 11SimpleClassAAC")-1
+	.byte	0
+
+	.section	__TEXT,__swift5_fieldmd
+	.p2align	2, 0x0
+_$s11SimpleClassAACMF:
+	.long	"_symbolic _____ 11SimpleClassAAC"-_$s11SimpleClassAACMF
+	.long	("_symbolic So8NSObjectC"-_$s11SimpleClassAACMF)-4
+	.short	7
+	.short	12
+	.long	0
+
+	.section	__TEXT,__objc_methname,cstring_literals
+"L_selector_data(categoryInstanceMethod)":
+	.asciz	"categoryInstanceMethod"
+
+	.section	__TEXT,__cstring,cstring_literals
+"l_.str.7.q16 at 0:8":
+	.asciz	"q16 at 0:8"
+
+	.section	__DATA,__objc_data
+	.p2align	3, 0x0
+__CATEGORY_INSTANCE_METHODS__TtC11SimpleClass11SimpleClass_$_SimpleClass:
+	.long	24
+	.long	1
+	.quad	"L_selector_data(categoryInstanceMethod)"
+	.quad	"l_.str.7.q16 at 0:8"
+	.quad	_$s11SimpleClassAAC22categoryInstanceMethodSiyFTo
+
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0
+__CATEGORY__TtC11SimpleClass11SimpleClass_$_SimpleClass:
+	.quad	l_.str.11.SimpleClass
+	.quad	_$s11SimpleClassAACMf+24
+	.quad	__CATEGORY_INSTANCE_METHODS__TtC11SimpleClass11SimpleClass_$_SimpleClass
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.long	60
+	.space	4
+
+	.section	__TEXT,__swift5_types
+	.p2align	2, 0x0
+l_$s11SimpleClassAACHn:
+	.long	_$s11SimpleClassAACMn-l_$s11SimpleClassAACHn
+
+	.private_extern	___swift_reflection_version
+	.section	__TEXT,__const
+	.globl	___swift_reflection_version
+	.weak_definition	___swift_reflection_version
+	.p2align	1, 0x0
+___swift_reflection_version:
+	.short	3
+
+	.section	__DATA,__objc_classlist,regular,no_dead_strip
+	.p2align	3, 0x0
+_objc_classes_$s11SimpleClassAACN:
+	.quad	_$s11SimpleClassAACN
+
+	.section	__DATA,__objc_catlist,regular,no_dead_strip
+	.p2align	3, 0x0
+_objc_categories:
+	.quad	__CATEGORY__TtC11SimpleClass11SimpleClass_$_SimpleClass
+
+	.no_dead_strip	_main
+	.no_dead_strip	l_entry_point
+	.no_dead_strip	_$s11SimpleClassAACMF
+	.no_dead_strip	l_$s11SimpleClassAACHn
+	.no_dead_strip	___swift_reflection_version
+	.no_dead_strip	_objc_classes_$s11SimpleClassAACN
+	.no_dead_strip	_objc_categories
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	100665152
+
+	.globl	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyFTq
+	.private_extern	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyFTq
+	.alt_entry	_$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyFTq
+.set _$s11SimpleClassAAC04baseB14InstanceMethods5Int32VyFTq, _$s11SimpleClassAACMn+52
+	.globl	_$s11SimpleClassAACN
+	.private_extern	_$s11SimpleClassAACN
+	.alt_entry	_$s11SimpleClassAACN
+.set _$s11SimpleClassAACN, _$s11SimpleClassAACMf+24
+	.globl	_OBJC_CLASS_$__TtC11SimpleClass11SimpleClass
+	.private_extern	_OBJC_CLASS_$__TtC11SimpleClass11SimpleClass
+.subsections_via_symbols
+
+_OBJC_CLASS_$_NSObject:
+_OBJC_METACLASS_$_NSObject:
+__objc_empty_cache:
+_$sBOWV:
+  .quad 0



More information about the llvm-commits mailing list