]> git.saurik.com Git - apple/objc4.git/blame - test/lazyClassName.m
objc4-818.2.tar.gz
[apple/objc4.git] / test / lazyClassName.m
CommitLineData
34d5b5e8
A
1/*
2TEST_RUN_OUTPUT
3LazyClassName
4LazyClassName2
5END
6*/
7
8#include "test.h"
9#include "testroot.i"
10
11typedef const char * _Nullable (*objc_hook_lazyClassNamer)(_Nonnull Class);
12
13void objc_setHook_lazyClassNamer(_Nonnull objc_hook_lazyClassNamer newValue,
14 _Nonnull objc_hook_lazyClassNamer * _Nonnull oldOutValue);
15
16#define RW_COPIED_RO (1<<27)
17
18struct 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
26struct 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
48extern struct ObjCClass OBJC_METACLASS_$_NSObject;
49extern struct ObjCClass OBJC_CLASS_$_NSObject;
50
51extern struct ObjCClass LazyClassName;
52extern struct ObjCClass LazyClassName2;
53
54struct ObjCClass_ro LazyClassNameMetaclass_ro = {
55 .flags = 1,
56 .instanceStart = 40,
57 .instanceSize = 40,
58 .nonMetaClass = &LazyClassName,
59};
60
61struct 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
68struct ObjCClass_ro LazyClassName_ro = {
69 .instanceStart = 8,
70 .instanceSize = 8,
71};
72
73struct ObjCClass LazyClassName = {
74 .isa = &LazyClassNameMetaclass,
75 .superclass = &OBJC_CLASS_$_NSObject,
76 .cachePtr = &_objc_empty_cache,
77 .data = (uintptr_t)&LazyClassName_ro + 2,
78};
79
80struct ObjCClass_ro LazyClassName2Metaclass_ro = {
81 .flags = 1,
82 .instanceStart = 40,
83 .instanceSize = 40,
84 .nonMetaClass = &LazyClassName2,
85};
86
87struct 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
94struct ObjCClass_ro LazyClassName2_ro = {
95 .instanceStart = 8,
96 .instanceSize = 8,
97};
98
99struct ObjCClass LazyClassName2 = {
100 .isa = &LazyClassName2Metaclass,
101 .superclass = &OBJC_CLASS_$_NSObject,
102 .cachePtr = &_objc_empty_cache,
103 .data = (uintptr_t)&LazyClassName2_ro + 2,
104};
105
106static objc_hook_lazyClassNamer OrigNamer;
107
108static const char *ClassNamer(Class cls) {
109 if (cls == (__bridge Class)&LazyClassName)
110 return "LazyClassName";
111 return OrigNamer(cls);
112}
113
114static objc_hook_lazyClassNamer OrigNamer2;
115
116static 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")))
123struct ObjCClass *LazyClassNamePtr = &LazyClassName;
124__attribute__((section("__DATA,__objc_classlist,regular,no_dead_strip")))
125struct ObjCClass *LazyClassNamePtr2 = &LazyClassName2;
126
127int 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}