darling-objc4/test/methodListSmall.h
2022-03-31 21:15:07 -07:00

237 lines
5.1 KiB
Objective-C

#include "test.h"
struct ObjCClass {
struct ObjCClass * __ptrauth_objc_isa_pointer isa;
struct ObjCClass * __ptrauth_objc_super_pointer superclass;
void *cachePtr;
uintptr_t zero;
struct ObjCClass_ro *data;
};
struct ObjCClass_ro {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name;
struct ObjCMethodList * __ptrauth_objc_method_list_pointer baseMethodList;
struct protocol_list_t * baseProtocols;
const struct ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
struct property_list_t *baseProperties;
};
struct ObjCMethod {
char *name;
char *type;
IMP imp;
};
struct ObjCMethodList {
uint32_t sizeAndFlags;
uint32_t count;
struct ObjCMethod methods[];
};
struct ObjCMethodSmall {
int32_t nameOffset;
int32_t typeOffset;
int32_t impOffset;
};
struct ObjCMethodListSmall {
uint32_t sizeAndFlags;
uint32_t count;
struct ObjCMethodSmall methods[];
};
extern struct ObjCClass OBJC_METACLASS_$_NSObject;
extern struct ObjCClass OBJC_CLASS_$_NSObject;
struct ObjCClass_ro FooMetaclass_ro = {
.flags = 1,
.instanceStart = 40,
.instanceSize = 40,
.name = "Foo",
};
struct ObjCClass FooMetaclass = {
.isa = &OBJC_METACLASS_$_NSObject,
.superclass = &OBJC_METACLASS_$_NSObject,
.cachePtr = &_objc_empty_cache,
.data = &FooMetaclass_ro,
};
int ranMyMethod1;
extern "C" void myMethod1(id self __unused, SEL _cmd) {
testprintf("myMethod1\n");
testassert(_cmd == @selector(myMethod1));
ranMyMethod1 = 1;
}
int ranMyMethod2;
extern "C" void myMethod2(id self __unused, SEL _cmd) {
testprintf("myMethod2\n");
testassert(_cmd == @selector(myMethod2));
ranMyMethod2 = 1;
}
int ranMyMethod3;
extern "C" void myMethod3(id self __unused, SEL _cmd) {
testprintf("myMethod3\n");
testassert(_cmd == @selector(myMethod3));
ranMyMethod3 = 1;
}
int ranMyReplacedMethod1;
extern "C" void myReplacedMethod1(id self __unused, SEL _cmd) {
testprintf("myReplacedMethod1\n");
testassert(_cmd == @selector(myMethod1));
ranMyReplacedMethod1 = 1;
}
int ranMyReplacedMethod2;
extern "C" void myReplacedMethod2(id self __unused, SEL _cmd) {
testprintf("myReplacedMethod2\n");
testassert(_cmd == @selector(myMethod2));
ranMyReplacedMethod2 = 1;
}
struct BigStruct {
uintptr_t a, b, c, d, e, f, g;
};
int ranMyMethodStret;
extern "C" BigStruct myMethodStret(id self __unused, SEL _cmd) {
testprintf("myMethodStret\n");
testassert(_cmd == @selector(myMethodStret));
ranMyMethodStret = 1;
BigStruct ret = {};
return ret;
}
int ranMyReplacedMethodStret;
extern "C" BigStruct myReplacedMethodStret(id self __unused, SEL _cmd) {
testprintf("myReplacedMethodStret\n");
testassert(_cmd == @selector(myMethodStret));
ranMyReplacedMethodStret = 1;
BigStruct ret = {};
return ret;
}
extern struct ObjCMethodList Foo_methodlistSmall;
asm(R"ASM(
.section __TEXT,__cstring
_MyMethod1Name:
.asciz "myMethod1"
_MyMethod2Name:
.asciz "myMethod2"
_MyMethod3Name:
.asciz "myMethod3"
_BoringMethodType:
.asciz "v16@0:8"
_MyMethodStretName:
.asciz "myMethodStret"
_MyMethodNullTypesName:
.asciz "myMethodNullTypes"
_StretType:
.asciz "{BigStruct=QQQQQQQ}16@0:8"
)ASM");
#if __LP64__
asm(R"ASM(
.section __DATA,__objc_selrefs,literal_pointers,no_dead_strip
_MyMethod1NameRef:
.quad _MyMethod1Name
_MyMethod2NameRef:
.quad _MyMethod2Name
_MyMethod3NameRef:
.quad _MyMethod3Name
_MyMethodStretNameRef:
.quad _MyMethodStretName
_MyMethodNullTypesNameRef:
.quad _MyMethodNullTypesName
)ASM");
#else
asm(R"ASM(
.section __DATA,__objc_selrefs,literal_pointers,no_dead_strip
_MyMethod1NameRef:
.long _MyMethod1Name
_MyMethod2NameRef:
.long _MyMethod2Name
_MyMethod3NameRef:
.long _MyMethod3Name
_MyMethodStretNameRef:
.long _MyMethodStretName
_MyMethodNullTypesNameRef:
.long _MyMethodNullTypesName
)ASM");
#endif
#if MUTABLE_METHOD_LIST
asm(".section __DATA,__objc_methlist\n");
#else
asm(".section __TEXT,__objc_methlist\n");
#endif
asm(R"ASM(
.p2align 2
_Foo_methodlistSmall:
.long 12 | 0x80000000
.long 5
.long _MyMethod1NameRef - .
.long _BoringMethodType - .
.long _myMethod1 - .
.long _MyMethod2NameRef - .
.long _BoringMethodType - .
.long _myMethod2 - .
.long _MyMethod3NameRef - .
.long _BoringMethodType - .
.long _myMethod3 - .
.long _MyMethodStretNameRef - .
.long _StretType - .
.long _myMethodStret - .
.long _MyMethodNullTypesNameRef - .
.long 0
.long _myMethod1 - .
)ASM");
struct ObjCClass_ro Foo_ro = {
.instanceStart = 8,
.instanceSize = 8,
.name = "Foo",
.baseMethodList = &Foo_methodlistSmall,
};
struct ObjCClass FooClass = {
.isa = &FooMetaclass,
.superclass = &OBJC_CLASS_$_NSObject,
.cachePtr = &_objc_empty_cache,
.data = &Foo_ro,
};
@interface Foo: NSObject
- (void)myMethod1;
- (void)myMethod2;
- (void)myMethod3;
- (BigStruct)myMethodStret;
@end