Skip to content

Commit 0f286f8

Browse files
authored
[ORC][MachO] Register objc protolist, protorefs, nlclslist metadata sections (#95144)
Add missing __DATA sections that the objc runtime expects to register. This fixes running objc code that makes use of `@protocol` references and `__attribute__((objc_nonlazy_class))` classes. rdar://129368761
1 parent 2b6c6bb commit 0f286f8

File tree

9 files changed

+633
-15
lines changed

9 files changed

+633
-15
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Test that we register non-lazy classes by ensuring a +load is called even if
2+
// the class is never referenced.
3+
//
4+
// RUN: %clang -c -o %t.o %s
5+
// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
6+
//
7+
// REQUIRES: jit-compatible-osx-swift-runtime
8+
9+
10+
.section __TEXT,__text,regular,pure_instructions
11+
.build_version macos, 15, 0 sdk_version 15, 0
12+
.p2align 2 ; -- Begin function +[C load]
13+
"+[C load]": ; @"\01+[C load]"
14+
.cfi_startproc
15+
; %bb.0:
16+
sub sp, sp, #16
17+
.cfi_def_cfa_offset 16
18+
str x0, [sp, #8]
19+
str x1, [sp]
20+
adrp x9, _x@PAGE
21+
mov w8, #7 ; =0x7
22+
str w8, [x9, _x@PAGEOFF]
23+
add sp, sp, #16
24+
ret
25+
.cfi_endproc
26+
; -- End function
27+
.globl _main ; -- Begin function main
28+
.p2align 2
29+
_main: ; @main
30+
.cfi_startproc
31+
; %bb.0:
32+
sub sp, sp, #16
33+
.cfi_def_cfa_offset 16
34+
str wzr, [sp, #12]
35+
adrp x8, _x@PAGE
36+
ldr w8, [x8, _x@PAGEOFF]
37+
subs w8, w8, #7
38+
cset w8, eq
39+
and w8, w8, #0x1
40+
ands w8, w8, #0x1
41+
cset w0, eq
42+
add sp, sp, #16
43+
ret
44+
.cfi_endproc
45+
; -- End function
46+
.globl _x ; @x
47+
.zerofill __DATA,__common,_x,4,2
48+
.section __DATA,__objc_data
49+
.globl _OBJC_CLASS_$_C ; @"OBJC_CLASS_$_C"
50+
.p2align 3, 0x0
51+
_OBJC_CLASS_$_C:
52+
.quad _OBJC_METACLASS_$_C
53+
.quad 0
54+
.quad __objc_empty_cache
55+
.quad 0
56+
.quad __OBJC_CLASS_RO_$_C
57+
58+
.globl _OBJC_METACLASS_$_C ; @"OBJC_METACLASS_$_C"
59+
.p2align 3, 0x0
60+
_OBJC_METACLASS_$_C:
61+
.quad _OBJC_METACLASS_$_C
62+
.quad _OBJC_CLASS_$_C
63+
.quad __objc_empty_cache
64+
.quad 0
65+
.quad __OBJC_METACLASS_RO_$_C
66+
67+
.section __TEXT,__objc_classname,cstring_literals
68+
l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_
69+
.asciz "C"
70+
71+
.section __TEXT,__objc_methname,cstring_literals
72+
l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_
73+
.asciz "load"
74+
75+
.section __TEXT,__objc_methtype,cstring_literals
76+
l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_
77+
.asciz "v16@0:8"
78+
79+
.section __DATA,__objc_const
80+
.p2align 3, 0x0 ; @"_OBJC_$_CLASS_METHODS_C"
81+
__OBJC_$_CLASS_METHODS_C:
82+
.long 24 ; 0x18
83+
.long 1 ; 0x1
84+
.quad l_OBJC_METH_VAR_NAME_
85+
.quad l_OBJC_METH_VAR_TYPE_
86+
.quad "+[C load]"
87+
88+
.p2align 3, 0x0 ; @"_OBJC_METACLASS_RO_$_C"
89+
__OBJC_METACLASS_RO_$_C:
90+
.long 3 ; 0x3
91+
.long 40 ; 0x28
92+
.long 40 ; 0x28
93+
.space 4
94+
.quad 0
95+
.quad l_OBJC_CLASS_NAME_
96+
.quad __OBJC_$_CLASS_METHODS_C
97+
.quad 0
98+
.quad 0
99+
.quad 0
100+
.quad 0
101+
102+
.p2align 3, 0x0 ; @"_OBJC_CLASS_RO_$_C"
103+
__OBJC_CLASS_RO_$_C:
104+
.long 2 ; 0x2
105+
.long 0 ; 0x0
106+
.long 0 ; 0x0
107+
.space 4
108+
.quad 0
109+
.quad l_OBJC_CLASS_NAME_
110+
.quad 0
111+
.quad 0
112+
.quad 0
113+
.quad 0
114+
.quad 0
115+
116+
.section __DATA,__objc_classlist,regular,no_dead_strip
117+
.p2align 3, 0x0 ; @"OBJC_LABEL_CLASS_$"
118+
l_OBJC_LABEL_CLASS_$:
119+
.quad _OBJC_CLASS_$_C
120+
121+
.section __DATA,__objc_nlclslist,regular,no_dead_strip
122+
.p2align 3, 0x0 ; @"OBJC_LABEL_NONLAZY_CLASS_$"
123+
l_OBJC_LABEL_NONLAZY_CLASS_$:
124+
.quad _OBJC_CLASS_$_C
125+
126+
.section __DATA,__objc_imageinfo,regular,no_dead_strip
127+
L_OBJC_IMAGE_INFO:
128+
.long 0
129+
.long 64
130+
131+
.subsections_via_symbols
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Test that we register protocol reference metadata. Without registration,
2+
// protocol pointers will not be uniqued correctly and @protocol(NSObject) will
3+
// not match the runtime's pointer.
4+
//
5+
// RUN: %clang -c -o %t.o %s
6+
// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
7+
//
8+
// REQUIRES: jit-compatible-osx-swift-runtime
9+
10+
.section __TEXT,__text,regular,pure_instructions
11+
.build_version macos, 15, 0 sdk_version 15, 0
12+
.globl _main ; -- Begin function main
13+
.p2align 2
14+
_main: ; @main
15+
.cfi_startproc
16+
; %bb.0:
17+
sub sp, sp, #32
18+
stp x29, x30, [sp, #16] ; 16-byte Folded Spill
19+
add x29, sp, #16
20+
.cfi_def_cfa w29, 16
21+
.cfi_offset w30, -8
22+
.cfi_offset w29, -16
23+
stur wzr, [x29, #-4]
24+
adrp x8, __OBJC_PROTOCOL_REFERENCE_$_NSObject@PAGE
25+
ldr x8, [x8, __OBJC_PROTOCOL_REFERENCE_$_NSObject@PAGEOFF]
26+
str x8, [sp] ; 8-byte Folded Spill
27+
adrp x0, l_.str@PAGE
28+
add x0, x0, l_.str@PAGEOFF
29+
bl _objc_getProtocol
30+
ldr x8, [sp] ; 8-byte Folded Reload
31+
subs x8, x8, x0
32+
cset w8, eq
33+
and w8, w8, #0x1
34+
ands w8, w8, #0x1
35+
cset w0, eq
36+
ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
37+
add sp, sp, #32
38+
ret
39+
.cfi_endproc
40+
; -- End function
41+
.section __TEXT,__objc_classname,cstring_literals
42+
l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_
43+
.asciz "NSObject"
44+
45+
.private_extern __OBJC_PROTOCOL_$_NSObject ; @"_OBJC_PROTOCOL_$_NSObject"
46+
.section __DATA,__data
47+
.globl __OBJC_PROTOCOL_$_NSObject
48+
.weak_definition __OBJC_PROTOCOL_$_NSObject
49+
.p2align 3, 0x0
50+
__OBJC_PROTOCOL_$_NSObject:
51+
.quad 0
52+
.quad l_OBJC_CLASS_NAME_
53+
.quad 0
54+
.quad 0
55+
.quad 0
56+
.quad 0
57+
.quad 0
58+
.quad 0
59+
.long 96 ; 0x60
60+
.long 0 ; 0x0
61+
.quad 0
62+
.quad 0
63+
.quad 0
64+
65+
.private_extern __OBJC_LABEL_PROTOCOL_$_NSObject ; @"_OBJC_LABEL_PROTOCOL_$_NSObject"
66+
.section __DATA,__objc_protolist,coalesced,no_dead_strip
67+
.globl __OBJC_LABEL_PROTOCOL_$_NSObject
68+
.weak_definition __OBJC_LABEL_PROTOCOL_$_NSObject
69+
.p2align 3, 0x0
70+
__OBJC_LABEL_PROTOCOL_$_NSObject:
71+
.quad __OBJC_PROTOCOL_$_NSObject
72+
73+
.private_extern __OBJC_PROTOCOL_REFERENCE_$_NSObject ; @"_OBJC_PROTOCOL_REFERENCE_$_NSObject"
74+
.section __DATA,__objc_protorefs,coalesced,no_dead_strip
75+
.globl __OBJC_PROTOCOL_REFERENCE_$_NSObject
76+
.weak_definition __OBJC_PROTOCOL_REFERENCE_$_NSObject
77+
.p2align 3, 0x0
78+
__OBJC_PROTOCOL_REFERENCE_$_NSObject:
79+
.quad __OBJC_PROTOCOL_$_NSObject
80+
81+
.section __TEXT,__cstring,cstring_literals
82+
l_.str: ; @.str
83+
.asciz "NSObject"
84+
85+
.no_dead_strip __OBJC_PROTOCOL_$_NSObject
86+
.no_dead_strip __OBJC_LABEL_PROTOCOL_$_NSObject
87+
.no_dead_strip __OBJC_PROTOCOL_REFERENCE_$_NSObject
88+
.section __DATA,__objc_imageinfo,regular,no_dead_strip
89+
L_OBJC_IMAGE_INFO:
90+
.long 0
91+
.long 64
92+
93+
.subsections_via_symbols
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Test that we register protocol metadata. Without registration, messaging
2+
// a protocol metatype object crashes.
3+
//
4+
// RUN: %clang -c -o %t.o %s
5+
// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
6+
//
7+
// REQUIRES: jit-compatible-osx-swift-runtime
8+
9+
.section __TEXT,__text,regular,pure_instructions
10+
.build_version macos, 15, 0 sdk_version 15, 0
11+
.globl _main ; -- Begin function main
12+
.p2align 2
13+
_main: ; @main
14+
.cfi_startproc
15+
; %bb.0:
16+
sub sp, sp, #32
17+
stp x29, x30, [sp, #16] ; 16-byte Folded Spill
18+
add x29, sp, #16
19+
.cfi_def_cfa w29, 16
20+
.cfi_offset w30, -8
21+
.cfi_offset w29, -16
22+
mov w8, #0 ; =0x0
23+
str w8, [sp, #8] ; 4-byte Folded Spill
24+
stur wzr, [x29, #-4]
25+
adrp x8, __OBJC_PROTOCOL_REFERENCE_$_P@PAGE
26+
ldr x0, [x8, __OBJC_PROTOCOL_REFERENCE_$_P@PAGEOFF]
27+
bl _objc_retain
28+
ldr w0, [sp, #8] ; 4-byte Folded Reload
29+
ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
30+
add sp, sp, #32
31+
ret
32+
.cfi_endproc
33+
; -- End function
34+
.section __TEXT,__objc_classname,cstring_literals
35+
l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_
36+
.asciz "P"
37+
38+
.private_extern __OBJC_PROTOCOL_$_P ; @"_OBJC_PROTOCOL_$_P"
39+
.section __DATA,__data
40+
.globl __OBJC_PROTOCOL_$_P
41+
.weak_definition __OBJC_PROTOCOL_$_P
42+
.p2align 3, 0x0
43+
__OBJC_PROTOCOL_$_P:
44+
.quad 0
45+
.quad l_OBJC_CLASS_NAME_
46+
.quad 0
47+
.quad 0
48+
.quad 0
49+
.quad 0
50+
.quad 0
51+
.quad 0
52+
.long 96 ; 0x60
53+
.long 0 ; 0x0
54+
.quad 0
55+
.quad 0
56+
.quad 0
57+
58+
.private_extern __OBJC_LABEL_PROTOCOL_$_P ; @"_OBJC_LABEL_PROTOCOL_$_P"
59+
.section __DATA,__objc_protolist,coalesced,no_dead_strip
60+
.globl __OBJC_LABEL_PROTOCOL_$_P
61+
.weak_definition __OBJC_LABEL_PROTOCOL_$_P
62+
.p2align 3, 0x0
63+
__OBJC_LABEL_PROTOCOL_$_P:
64+
.quad __OBJC_PROTOCOL_$_P
65+
66+
.private_extern __OBJC_PROTOCOL_REFERENCE_$_P ; @"_OBJC_PROTOCOL_REFERENCE_$_P"
67+
.section __DATA,__objc_protorefs,coalesced,no_dead_strip
68+
.globl __OBJC_PROTOCOL_REFERENCE_$_P
69+
.weak_definition __OBJC_PROTOCOL_REFERENCE_$_P
70+
.p2align 3, 0x0
71+
__OBJC_PROTOCOL_REFERENCE_$_P:
72+
.quad __OBJC_PROTOCOL_$_P
73+
74+
.no_dead_strip __OBJC_PROTOCOL_$_P
75+
.no_dead_strip __OBJC_LABEL_PROTOCOL_$_P
76+
.no_dead_strip __OBJC_PROTOCOL_REFERENCE_$_P
77+
.section __DATA,__objc_imageinfo,regular,no_dead_strip
78+
L_OBJC_IMAGE_INFO:
79+
.long 0
80+
.long 64
81+
82+
.subsections_via_symbols

0 commit comments

Comments
 (0)