]> git.saurik.com Git - apple/objc4.git/blob - test/lazyClassName.m
objc4-818.2.tar.gz
[apple/objc4.git] / test / lazyClassName.m
1 /*
2 TEST_RUN_OUTPUT
3 LazyClassName
4 LazyClassName2
5 END
6 */
7
8 #include "test.h"
9 #include "testroot.i"
10
11 typedef const char * _Nullable (*objc_hook_lazyClassNamer)(_Nonnull Class);
12
13 void objc_setHook_lazyClassNamer(_Nonnull objc_hook_lazyClassNamer newValue,
14 _Nonnull objc_hook_lazyClassNamer * _Nonnull oldOutValue);
15
16 #define RW_COPIED_RO (1<<27)
17
18 struct ObjCClass {
19 struct ObjCClass * __ptrauth_objc_isa_pointer isa;
20 struct ObjCClass * __ptrauth_objc_super_pointer superclass;
21 void *cachePtr;
22 uintptr_t zero;
23 uintptr_t data;
24 };
25
26 struct ObjCClass_ro {
27 uint32_t flags;
28 uint32_t instanceStart;
29 uint32_t instanceSize;
30 #ifdef __LP64__
31 uint32_t reserved;
32 #endif
33
34 union {
35 const uint8_t * ivarLayout;
36 struct ObjCClass * nonMetaClass;
37 };
38
39 const char * name;
40 struct ObjCMethodList * __ptrauth_objc_method_list_pointer baseMethodList;
41 struct protocol_list_t * baseProtocols;
42 const struct ivar_list_t * ivars;
43
44 const uint8_t * weakIvarLayout;
45 struct property_list_t *baseProperties;
46 };
47
48 extern struct ObjCClass OBJC_METACLASS_$_NSObject;
49 extern struct ObjCClass OBJC_CLASS_$_NSObject;
50
51 extern struct ObjCClass LazyClassName;
52 extern struct ObjCClass LazyClassName2;
53
54 struct ObjCClass_ro LazyClassNameMetaclass_ro = {
55 .flags = 1,
56 .instanceStart = 40,
57 .instanceSize = 40,
58 .nonMetaClass = &LazyClassName,
59 };
60
61 struct ObjCClass LazyClassNameMetaclass = {
62 .isa = &OBJC_METACLASS_$_NSObject,
63 .superclass = &OBJC_METACLASS_$_NSObject,
64 .cachePtr = &_objc_empty_cache,
65 .data = (uintptr_t)&LazyClassNameMetaclass_ro,
66 };
67
68 struct ObjCClass_ro LazyClassName_ro = {
69 .instanceStart = 8,
70 .instanceSize = 8,
71 };
72
73 struct ObjCClass LazyClassName = {
74 .isa = &LazyClassNameMetaclass,
75 .superclass = &OBJC_CLASS_$_NSObject,
76 .cachePtr = &_objc_empty_cache,
77 .data = (uintptr_t)&LazyClassName_ro + 2,
78 };
79
80 struct ObjCClass_ro LazyClassName2Metaclass_ro = {
81 .flags = 1,
82 .instanceStart = 40,
83 .instanceSize = 40,
84 .nonMetaClass = &LazyClassName2,
85 };
86
87 struct ObjCClass LazyClassName2Metaclass = {
88 .isa = &OBJC_METACLASS_$_NSObject,
89 .superclass = &OBJC_METACLASS_$_NSObject,
90 .cachePtr = &_objc_empty_cache,
91 .data = (uintptr_t)&LazyClassName2Metaclass_ro,
92 };
93
94 struct ObjCClass_ro LazyClassName2_ro = {
95 .instanceStart = 8,
96 .instanceSize = 8,
97 };
98
99 struct ObjCClass LazyClassName2 = {
100 .isa = &LazyClassName2Metaclass,
101 .superclass = &OBJC_CLASS_$_NSObject,
102 .cachePtr = &_objc_empty_cache,
103 .data = (uintptr_t)&LazyClassName2_ro + 2,
104 };
105
106 static objc_hook_lazyClassNamer OrigNamer;
107
108 static const char *ClassNamer(Class cls) {
109 if (cls == (__bridge Class)&LazyClassName)
110 return "LazyClassName";
111 return OrigNamer(cls);
112 }
113
114 static objc_hook_lazyClassNamer OrigNamer2;
115
116 static const char *ClassNamer2(Class cls) {
117 if (cls == (__bridge Class)&LazyClassName2)
118 return "LazyClassName2";
119 return OrigNamer2(cls);
120 }
121
122 __attribute__((section("__DATA,__objc_classlist,regular,no_dead_strip")))
123 struct ObjCClass *LazyClassNamePtr = &LazyClassName;
124 __attribute__((section("__DATA,__objc_classlist,regular,no_dead_strip")))
125 struct ObjCClass *LazyClassNamePtr2 = &LazyClassName2;
126
127 int main() {
128 #pragma clang diagnostic push
129 #pragma clang diagnostic ignored "-Wunguarded-availability"
130 objc_setHook_lazyClassNamer(ClassNamer, &OrigNamer);
131 objc_setHook_lazyClassNamer(ClassNamer2, &OrigNamer2);
132 #pragma clang diagnostic pop
133
134 printf("%s\n", class_getName([(__bridge id)&LazyClassName class]));
135 printf("%s\n", class_getName([(__bridge id)&LazyClassName2 class]));
136 }