diff --git a/src/libobjcdarwin/new/class.cpp b/src/libobjcdarwin/new/class.cpp index 7e465c5e5..11421fd2d 100644 --- a/src/libobjcdarwin/new/class.cpp +++ b/src/libobjcdarwin/new/class.cpp @@ -84,9 +84,15 @@ void ProcessClassesNew(const struct mach_header* mh, intptr_t slide, const class Class c = RegisterClass(cls, slide); if (class_refs) + { find_and_fix(class_refs, class_refs_end, cls, c); + find_and_fix(class_refs, class_refs_end, cls->isa, object_getClass(id(c))); + } if (super_refs) + { find_and_fix(super_refs, super_refs_end, cls, c); + find_and_fix(super_refs, super_refs_end, cls->isa, object_getClass(id(c))); + } } } diff --git a/src/libobjcdarwin/objc_msgSendSuper.nasm b/src/libobjcdarwin/objc_msgSendSuper.nasm index b46e3c5b9..a3959d9af 100644 --- a/src/libobjcdarwin/objc_msgSendSuper.nasm +++ b/src/libobjcdarwin/objc_msgSendSuper.nasm @@ -108,7 +108,7 @@ section text mov eax, [esp-4] ; restore the IMP %endmacro -__darwin_objc_msgSendSuper2: +__darwin_objc_msgSendSuper: mov eax, [esp+4] ; get objc_super* ; make a copy on the stack mov ecx, [eax] ; 1st elem @@ -120,7 +120,7 @@ __darwin_objc_msgSendSuper2: sub esp, 8 mov eax, [esp+16]; SEL (2nd argument) push eax - lea eax, [esp+12]; fixed objc_super (1st argument) + lea eax, [esp+4]; fixed objc_super (1st argument) push eax call objc_msg_lookup_super @@ -131,7 +131,7 @@ __darwin_objc_msgSendSuper2: jmp eax -__darwin_objc_msgSendSuper: +__darwin_objc_msgSendSuper_xxx: mov eax, [esp+8] push eax diff --git a/src/libobjcdarwin/objc_msgSend_fixup.nasm b/src/libobjcdarwin/objc_msgSend_fixup.nasm index 43d75ae4a..367206e5e 100644 --- a/src/libobjcdarwin/objc_msgSend_fixup.nasm +++ b/src/libobjcdarwin/objc_msgSend_fixup.nasm @@ -1,7 +1,12 @@ global __darwin_objc_msgSend_fixup global objc_msgSendSuper2_fixup +global objc_msgSendSuper2_stret_fixup +global __darwin_objc_msgSend_fpret_fixup +global __darwin_objc_msgSend_fp2ret_fixup extern objc_msgSend +extern objc_msgSend_fpret extern __darwin_objc_msgSendSuper2 +extern __darwin_objc_msgSendSuper2_stret section .note.GNU-stack noalloc noexec nowrite progbits @@ -10,7 +15,10 @@ section .note.GNU-stack noalloc noexec nowrite progbits BITS 64 section text -; TODO: msgSendSuper2_fixup... +__darwin_objc_msgSend_fp2ret_fixup: +__darwin_objc_msgSend_fpret_fixup: + mov rsi, [rsi+8] + jmp objc_msgSend_fpret WRT ..plt __darwin_objc_msgSend_fixup: mov rsi, [rsi+8] @@ -20,6 +28,10 @@ objc_msgSendSuper2_fixup: mov rsi, [rsi+8] jmp __darwin_objc_msgSendSuper2 WRT ..plt +objc_msgSendSuper2_stret_fixup: + mov rdx, [rdx+8] + jmp __darwin_objc_msgSendSuper2_stret WRT ..plt + %elifidn __OUTPUT_FORMAT__, elf BITS 32 diff --git a/src/libobjcdarwin/old/class.cpp b/src/libobjcdarwin/old/class.cpp index d95b653d2..cac2c093d 100644 --- a/src/libobjcdarwin/old/class.cpp +++ b/src/libobjcdarwin/old/class.cpp @@ -134,7 +134,7 @@ void ProcessClassesOld(const struct mach_header* mh, intptr_t slide, module_info for (uint16_t i = 0; i < info->symtab->countClasses; i++) { old_class* cls = static_cast(info->symtab->classesAndCategories[i])->isa.cls; - Class c = (Class) objc_getClass(cls->name); + Class c = (Class) objc_getMetaClass(cls->name); LOG << "ObjC fixup super_class @" << cls << ": " << cls->name << " -> " << c << std::endl; cls->super_class.clsNew = c; } diff --git a/tests/src/objc_fpret.m b/tests/src/objc_fpret.m new file mode 100644 index 000000000..84ae23e2e --- /dev/null +++ b/tests/src/objc_fpret.m @@ -0,0 +1,42 @@ +// CFLAGS: -framework foundation + +// Bugs found: +// objc_superrefs not properly fixed at load time + +#import +#include +#include + +@interface baseclass : NSObject ++(long double)test; +@end + +@interface subclass : baseclass ++(long double)test; +@end + +@implementation baseclass ++(long double)test +{ + puts("Test called"); + return 5.0; +} +@end + +@implementation subclass ++(long double)test +{ + long double v = [super test]; + printf("After supercall: %Lf\n", v); + v += 1.0; + return v; +} +@end + +int main() +{ + long double v = [subclass test]; + printf("Return value: %Lf\n", v); + return 0; +} + diff --git a/tests/src/objc_stret.m b/tests/src/objc_stret.m index 00f7c20a0..9af3037a2 100644 --- a/tests/src/objc_stret.m +++ b/tests/src/objc_stret.m @@ -1,4 +1,5 @@ #include +#include #import struct st @@ -16,6 +17,8 @@ struct st @implementation helloclass + (struct st)mult:(float)a :(float)b { + assert(self == [helloclass class]); + struct st s; s.f1 = a+b; return s;