1# REQUIRES: aarch64 2# UNSUPPORTED: system-windows 3# due to awk usage 4 5# RUN: rm -rf %t; split-file %s %t && cd %t 6 7############ Test merging multiple categories into a single category ############ 8## Create a dylib with a fake base class to link against in when merging between categories 9# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_fakedylib.o a64_fakedylib.s 10# RUN: %lld -arch arm64 a64_fakedylib.o -o a64_fakedylib.dylib -dylib 11 12## Create our main testing dylib - linking against the fake dylib above 13# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s 14# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o 15# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o 16 17## Now verify that the flag caused category merging to happen appropriatelly 18# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_CATS 19# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_merge.dylib | FileCheck %s --check-prefixes=MERGE_CATS 20 21############ Test merging multiple categories into the base class ############ 22# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_base_class_minimal.o merge_base_class_minimal.s 23# RUN: %lld -arch arm64 -dylib -o merge_base_class_minimal_yes_merge.dylib -objc_category_merging merge_base_class_minimal.o merge_cat_minimal.o 24# RUN: %lld -arch arm64 -dylib -o merge_base_class_minimal_no_merge.dylib merge_base_class_minimal.o merge_cat_minimal.o 25 26# RUN: llvm-objdump --objc-meta-data --macho merge_base_class_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_INTO_BASE 27# RUN: llvm-objdump --objc-meta-data --macho merge_base_class_minimal_yes_merge.dylib | FileCheck %s --check-prefixes=YES_MERGE_INTO_BASE 28 29############ Test merging swift category into the base class ############ 30# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o MyBaseClassSwiftExtension.o MyBaseClassSwiftExtension.s 31# RUN: %lld -no_objc_relative_method_lists -arch arm64 -dylib -o merge_base_class_swift_minimal_yes_merge.dylib -objc_category_merging MyBaseClassSwiftExtension.o merge_base_class_minimal.o 32# RUN: llvm-objdump --objc-meta-data --macho merge_base_class_swift_minimal_yes_merge.dylib | FileCheck %s --check-prefixes=YES_MERGE_INTO_BASE_SWIFT 33 34############ Test merging skipped due to invalid category name ############ 35# Modify __OBJC_$_CATEGORY_MyBaseClass_$_Category01's name to point to L_OBJC_IMAGE_INFO+3 36# RUN: awk '/^__OBJC_\$_CATEGORY_MyBaseClass_\$_Category01:/ { print; getline; sub(/^[ \t]*\.quad[ \t]+l_OBJC_CLASS_NAME_$/, "\t.quad\tL_OBJC_IMAGE_INFO+3"); print; next } { print }' merge_cat_minimal.s > merge_cat_minimal_bad_name.s 37 38# Assemble the modified source 39# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal_bad_name.o merge_cat_minimal_bad_name.s 40 41# Run lld and check for the specific warning 42# RUN: %no-fatal-warnings-lld -arch arm64 -dylib -objc_category_merging -o merge_cat_minimal_merge.dylib a64_fakedylib.dylib merge_cat_minimal_bad_name.o 2>&1 | FileCheck %s --check-prefix=MERGE_WARNING 43 44# Check that lld emitted the warning about skipping category merging 45MERGE_WARNING: warning: ObjC category merging skipped for class symbol' _OBJC_CLASS_$_MyBaseClass' 46 47#### Check merge categories enabled ### 48# Check that the original categories are not there 49MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 50MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 51 52# Check that the merged cateogry is there, in the correct format 53MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02) 54MERGE_CATS-NEXT: name {{.*}} Category01|Category02 55MERGE_CATS: instanceMethods 56MERGE_CATS-NEXT: entsize 12 (relative) 57MERGE_CATS-NEXT: count 2 58MERGE_CATS-NEXT: name {{.*}} cat01_InstanceMethod 59MERGE_CATS-NEXT: types {{.*}} v16@0:8 60MERGE_CATS-NEXT: imp {{.*}} -[MyBaseClass(Category01) cat01_InstanceMethod] 61MERGE_CATS-NEXT: name {{.*}} cat02_InstanceMethod 62MERGE_CATS-NEXT: types {{.*}} v16@0:8 63MERGE_CATS-NEXT: imp {{.*}} -[MyBaseClass(Category02) cat02_InstanceMethod] 64MERGE_CATS-NEXT: classMethods 0x0 65MERGE_CATS-NEXT: protocols 0x0 66MERGE_CATS-NEXT: instanceProperties 0x0 67 68#### Check merge categories disabled ### 69# Check that the merged category is not there 70NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02) 71 72# Check that the original categories are there 73NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 74NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 75 76 77#### Check merge cateogires into base class is disabled #### 78NO_MERGE_INTO_BASE: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 79NO_MERGE_INTO_BASE: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 80 81#### Check merge cateogires into base class is enabled and categories are merged into base class #### 82YES_MERGE_INTO_BASE-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 83YES_MERGE_INTO_BASE-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 84 85YES_MERGE_INTO_BASE: _OBJC_CLASS_$_MyBaseClass 86YES_MERGE_INTO_BASE-NEXT: _OBJC_METACLASS_$_MyBaseClass 87YES_MERGE_INTO_BASE: baseMethods 88YES_MERGE_INTO_BASE-NEXT: entsize 12 (relative) 89YES_MERGE_INTO_BASE-NEXT: count 3 90YES_MERGE_INTO_BASE-NEXT: name {{.*}} cat01_InstanceMethod 91YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8 92YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass(Category01) cat01_InstanceMethod] 93YES_MERGE_INTO_BASE-NEXT: name {{.*}} cat02_InstanceMethod 94YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8 95YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass(Category02) cat02_InstanceMethod] 96YES_MERGE_INTO_BASE-NEXT: name {{.*}} baseInstanceMethod 97YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8 98YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass baseInstanceMethod] 99 100 101#### Check merge swift category into base class ### 102YES_MERGE_INTO_BASE_SWIFT: _OBJC_CLASS_$_MyBaseClass 103YES_MERGE_INTO_BASE_SWIFT-NEXT: _OBJC_METACLASS_$_MyBaseClass 104YES_MERGE_INTO_BASE_SWIFT: baseMethods 105YES_MERGE_INTO_BASE_SWIFT-NEXT: entsize 24 106YES_MERGE_INTO_BASE_SWIFT-NEXT: count 2 107YES_MERGE_INTO_BASE_SWIFT-NEXT: name {{.*}} swiftMethod 108YES_MERGE_INTO_BASE_SWIFT-NEXT: types {{.*}} v16@0:8 109YES_MERGE_INTO_BASE_SWIFT-NEXT: imp _$sSo11MyBaseClassC0abC14SwiftExtensionE11swiftMethodyyFTo 110YES_MERGE_INTO_BASE_SWIFT-NEXT: name {{.*}} baseInstanceMethod 111YES_MERGE_INTO_BASE_SWIFT-NEXT: types {{.*}} v16@0:8 112YES_MERGE_INTO_BASE_SWIFT-NEXT: imp -[MyBaseClass baseInstanceMethod] 113 114 115#--- a64_fakedylib.s 116 117 .section __DATA,__objc_data 118 .globl _OBJC_CLASS_$_MyBaseClass 119_OBJC_CLASS_$_MyBaseClass: 120 .quad 0 121 122#--- merge_cat_minimal.s 123 124; ================== Generated from ObjC: ================== 125; __attribute__((objc_root_class)) 126; @interface MyBaseClass 127; - (void)baseInstanceMethod; 128; @end 129; 130; @interface MyBaseClass(Category01) 131; - (void)cat01_InstanceMethod; 132; @end 133; 134; @implementation MyBaseClass(Category01) 135; - (void)cat01_InstanceMethod {} 136; @end 137; 138; @interface MyBaseClass(Category02) 139; - (void)cat02_InstanceMethod; 140; @end 141; 142; @implementation MyBaseClass(Category02) 143; - (void)cat02_InstanceMethod {} 144; @end 145; ================== Generated from ObjC: ================== 146 147 .section __TEXT,__text,regular,pure_instructions 148 .p2align 2 ; -- Begin function -[MyBaseClass(Category01) cat01_InstanceMethod] 149"-[MyBaseClass(Category01) cat01_InstanceMethod]": ; @"\01-[MyBaseClass(Category01) cat01_InstanceMethod]" 150 .cfi_startproc 151 ret 152 .cfi_endproc 153 ; -- End function 154 .p2align 2 ; -- Begin function -[MyBaseClass(Category02) cat02_InstanceMethod] 155"-[MyBaseClass(Category02) cat02_InstanceMethod]": ; @"\01-[MyBaseClass(Category02) cat02_InstanceMethod]" 156 .cfi_startproc 157 ret 158 .cfi_endproc 159 ; -- End function 160 .section __TEXT,__objc_classname,cstring_literals 161l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ 162 .asciz "Category01" 163 .section __TEXT,__objc_methname,cstring_literals 164l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ 165 .asciz "cat01_InstanceMethod" 166 .section __TEXT,__objc_methtype,cstring_literals 167l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ 168 .asciz "v16@0:8" 169 .section __DATA,__objc_const 170 .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01" 171__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01: 172 .long 24 ; 0x18 173 .long 1 ; 0x1 174 .quad l_OBJC_METH_VAR_NAME_ 175 .quad l_OBJC_METH_VAR_TYPE_ 176 .quad "-[MyBaseClass(Category01) cat01_InstanceMethod]" 177 .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category01" 178__OBJC_$_CATEGORY_MyBaseClass_$_Category01: 179 .quad l_OBJC_CLASS_NAME_ 180 .quad _OBJC_CLASS_$_MyBaseClass 181 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01 182 .quad 0 183 .quad 0 184 .quad 0 185 .quad 0 186 .long 64 ; 0x40 187 .space 4 188 .section __DATA,__objc_const 189l_OBJC_CLASS_NAME_.1: ; @OBJC_CLASS_NAME_.1 190 .asciz "Category02" 191 .section __TEXT,__objc_methname,cstring_literals 192l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 193 .asciz "cat02_InstanceMethod" 194 .section __DATA,__objc_const 195 .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02" 196__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02: 197 .long 24 ; 0x18 198 .long 1 ; 0x1 199 .quad l_OBJC_METH_VAR_NAME_.2 200 .quad l_OBJC_METH_VAR_TYPE_ 201 .quad "-[MyBaseClass(Category02) cat02_InstanceMethod]" 202 .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02" 203__OBJC_$_CATEGORY_MyBaseClass_$_Category02: 204 .quad l_OBJC_CLASS_NAME_.1 205 .quad _OBJC_CLASS_$_MyBaseClass 206 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02 207 .quad 0 208 .quad 0 209 .quad 0 210 .quad 0 211 .long 64 ; 0x40 212 .space 4 213 .section __DATA,__objc_catlist,regular,no_dead_strip 214 .p2align 3, 0x0 ; @"OBJC_LABEL_CATEGORY_$" 215l_OBJC_LABEL_CATEGORY_$: 216 .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category01 217 .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category02 218 .section __DATA,__objc_imageinfo,regular,no_dead_strip 219L_OBJC_IMAGE_INFO: 220 .long 0 221 .long 96 222.subsections_via_symbols 223 224.addrsig 225.addrsig_sym __OBJC_$_CATEGORY_MyBaseClass_$_Category01 226 227#--- merge_base_class_minimal.s 228; clang -c merge_base_class_minimal.mm -O3 -target arm64-apple-macos -arch arm64 -S -o merge_base_class_minimal.s 229; ================== Generated from ObjC: ================== 230; __attribute__((objc_root_class)) 231; @interface MyBaseClass 232; - (void)baseInstanceMethod; 233; @end 234; 235; @implementation MyBaseClass 236; - (void)baseInstanceMethod {} 237; @end 238; ================== Generated from ObjC ================== 239 .section __TEXT,__text,regular,pure_instructions 240 .build_version macos, 11, 0 241 .p2align 2 242"-[MyBaseClass baseInstanceMethod]": 243 .cfi_startproc 244; %bb.0: 245 ret 246 .cfi_endproc 247 .section __DATA,__objc_data 248 .globl _OBJC_CLASS_$_MyBaseClass 249 .p2align 3, 0x0 250_OBJC_CLASS_$_MyBaseClass: 251 .quad _OBJC_METACLASS_$_MyBaseClass 252 .quad 0 253 .quad 0 254 .quad 0 255 .quad __OBJC_CLASS_RO_$_MyBaseClass 256 .globl _OBJC_METACLASS_$_MyBaseClass 257 .p2align 3, 0x0 258_OBJC_METACLASS_$_MyBaseClass: 259 .quad _OBJC_METACLASS_$_MyBaseClass 260 .quad _OBJC_CLASS_$_MyBaseClass 261 .quad 0 262 .quad 0 263 .quad __OBJC_METACLASS_RO_$_MyBaseClass 264 .section __TEXT,__objc_classname,cstring_literals 265l_OBJC_CLASS_NAME_: 266 .asciz "MyBaseClass" 267 .section __DATA,__objc_const 268 .p2align 3, 0x0 269__OBJC_METACLASS_RO_$_MyBaseClass: 270 .long 3 271 .long 40 272 .long 40 273 .space 4 274 .quad 0 275 .quad l_OBJC_CLASS_NAME_ 276 .quad 0 277 .quad 0 278 .quad 0 279 .quad 0 280 .quad 0 281 .section __TEXT,__objc_methname,cstring_literals 282l_OBJC_METH_VAR_NAME_: 283 .asciz "baseInstanceMethod" 284 .section __TEXT,__objc_methtype,cstring_literals 285l_OBJC_METH_VAR_TYPE_: 286 .asciz "v16@0:8" 287 .section __DATA,__objc_const 288 .p2align 3, 0x0 289__OBJC_$_INSTANCE_METHODS_MyBaseClass: 290 .long 24 291 .long 1 292 .quad l_OBJC_METH_VAR_NAME_ 293 .quad l_OBJC_METH_VAR_TYPE_ 294 .quad "-[MyBaseClass baseInstanceMethod]" 295 .p2align 3, 0x0 296__OBJC_CLASS_RO_$_MyBaseClass: 297 .long 2 298 .long 0 299 .long 0 300 .space 4 301 .quad 0 302 .quad l_OBJC_CLASS_NAME_ 303 .quad __OBJC_$_INSTANCE_METHODS_MyBaseClass 304 .quad 0 305 .quad 0 306 .quad 0 307 .quad 0 308 .section __DATA,__objc_classlist,regular,no_dead_strip 309 .p2align 3, 0x0 310l_OBJC_LABEL_CLASS_$: 311 .quad _OBJC_CLASS_$_MyBaseClass 312 .section __DATA,__objc_imageinfo,regular,no_dead_strip 313L_OBJC_IMAGE_INFO: 314 .long 0 315 .long 64 316.subsections_via_symbols 317 318 319#--- MyBaseClassSwiftExtension.s 320; xcrun -sdk macosx swiftc -emit-assembly MyBaseClassSwiftExtension.swift -import-objc-header YourProject-Bridging-Header.h -o MyBaseClassSwiftExtension.s 321; ================== Generated from Swift: ================== 322; import Foundation 323; extension MyBaseClass { 324; @objc func swiftMethod() { 325; } 326; } 327; ================== Generated from Swift =================== 328 .private_extern _$sSo11MyBaseClassC0abC14SwiftExtensionE11swiftMethodyyF 329 .globl _$sSo11MyBaseClassC0abC14SwiftExtensionE11swiftMethodyyF 330 .p2align 2 331_$sSo11MyBaseClassC0abC14SwiftExtensionE11swiftMethodyyF: 332 .cfi_startproc 333 mov w0, #0 334 ret 335 .cfi_endproc 336 337 .p2align 2 338_$sSo11MyBaseClassC0abC14SwiftExtensionE11swiftMethodyyFTo: 339 .cfi_startproc 340 mov w0, #0 341 ret 342 .cfi_endproc 343 344 .section __TEXT,__cstring,cstring_literals 345 .p2align 4, 0x0 346l_.str.25.MyBaseClassSwiftExtension: 347 .asciz "MyBaseClassSwiftExtension" 348 349 .section __TEXT,__objc_methname,cstring_literals 350"L_selector_data(swiftMethod)": 351 .asciz "swiftMethod" 352 353 .section __TEXT,__cstring,cstring_literals 354"l_.str.7.v16@0:8": 355 .asciz "v16@0:8" 356 357 .section __DATA,__objc_data 358 .p2align 3, 0x0 359__CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyBaseClassSwiftExtension: 360 .long 24 361 .long 1 362 .quad "L_selector_data(swiftMethod)" 363 .quad "l_.str.7.v16@0:8" 364 .quad _$sSo11MyBaseClassC0abC14SwiftExtensionE11swiftMethodyyFTo 365 366 .section __DATA,__objc_const 367 .p2align 3, 0x0 368__CATEGORY_MyBaseClass_$_MyBaseClassSwiftExtension: 369 .quad l_.str.25.MyBaseClassSwiftExtension 370 .quad _OBJC_CLASS_$_MyBaseClass 371 .quad __CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyBaseClassSwiftExtension 372 .quad 0 373 .quad 0 374 .quad 0 375 .quad 0 376 .long 60 377 .space 4 378 379 .section __DATA,__objc_catlist,regular,no_dead_strip 380 .p2align 3, 0x0 381_objc_categories: 382 .quad __CATEGORY_MyBaseClass_$_MyBaseClassSwiftExtension 383 384 .no_dead_strip _main 385 .no_dead_strip l_entry_point 386 387.subsections_via_symbols 388