Closed
Description
The libobjc2 objc_msgSend
implementation for aarch64 expects the receiver and selector to be passed in x0 and x1 respectively.
On Windows ARM64, the pointer to the (uninitialised) instance of the C++ Class is assigned to x0, shifting receiver and selector into x1 and x2. This results in a crash.
This does not happen on Ubuntu aarch64, as seen in the lldb snippet below.
I am using the GNUstep Windows SDK from https://github.com/gnustep/tools-windows-msvc.
Here is the test code:
#import <Foundation/Foundation.h>
class Bar
{
public:
Bar(int i) : m_i(i) {}
private:
int m_i;
};
@interface Test : NSObject
@end
@implementation Test
+ (Bar)bar
{
return Bar(42);
}
@end
int main(int argc, char *argv[])
{
NSLog(@"Hello");
auto pair = [Test bar]; // crashes
NSLog(@"Success");
return 0;
}
Windows 11 ARM64
Machine Information
WindowsBuildLabEx: 22621.1.arm64fre.ni_release.220506-1250
WindowsProductName: Windows 10 Pro
OSDisplayVersion: 23H2
WindowsKit: 10.0.22621.0
Clang Version
clang version 18.1.3
Target: aarch64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
Build Command (Inside MSYS2)
clang crash.mm -o crash.exe -g -gcodeview `gnustep-config --objc-flags` `gnustep-config --base-libs` -Xclang -fobjc-dispatch-method=non-legacy
LLDB
Process 6408 stopped
* thread #1, stop reason = breakpoint 2.1
frame #0: 0x00007ff738e61048 crash.exe`main(argc=867171612, argv=0x00007ff738e640b0) at crash.mm:27
24 {
25 NSLog(@"Hello");
26
-> 27 auto pair = [Test bar]; // crashes
28
29 NSLog(@"Success");
30
(lldb) di
crash.exe`main:
0x7ff738e6100c <+0>: sub sp, sp, #0x20
0x7ff738e61010 <+4>: str x19, [sp, #0x10]
0x7ff738e61014 <+8>: str x30, [sp, #0x18]
0x7ff738e61018 <+12>: mov x0, #0x2c ; =44
0x7ff738e6101c <+16>: adrp x19, 2
0x7ff738e61020 <+20>: movk x0, #0xe000, lsl #16
0x7ff738e61024 <+24>: ldr x19, [x19, #0x5e8]
0x7ff738e61028 <+28>: movk x0, #0x66cd, lsl #32
0x7ff738e6102c <+32>: movk x0, #0x9197, lsl #48
0x7ff738e61030 <+36>: blr x19
0x7ff738e61034 <+40>: adrp x8, 5
0x7ff738e61038 <+44>: adrp x2, 5
0x7ff738e6103c <+48>: add x2, x2, #0x10 ; __start_.objcrt$PCR
0x7ff738e61040 <+52>: ldr x1, [x8]
0x7ff738e61044 <+56>: add x0, sp, #0xc
-> 0x7ff738e61048 <+60>: bl 0x7ff738e62384 ; objc_msgSend_stret
0x7ff738e6104c <+64>: mov x0, #0x803c ; =32828
0x7ff738e61050 <+68>: movk x0, #0xbcf9, lsl #16
0x7ff738e61054 <+72>: movk x0, #0x1e3c, lsl #32
0x7ff738e61058 <+76>: movk x0, #0xa7d7, lsl #48
0x7ff738e6105c <+80>: blr x19
0x7ff738e61060 <+84>: mov w0, wzr
0x7ff738e61064 <+88>: ldr x30, [sp, #0x18]
0x7ff738e61068 <+92>: ldr x19, [sp, #0x10]
0x7ff738e6106c <+96>: add sp, sp, #0x20
0x7ff738e61070 <+100>: ret
(lldb) register read
General Purpose Registers:
x0 = 0x000000e233affd1c
x1 = 0x00007ff738e640b0 $_OBJC_CLASS_Test
x2 = 0x00007ff738e66010 __start_.objcrt$PCR
x3 = 0x0000000010000000
x4 = 0x0000000000000150
x5 = 0x000000006d9d3bcf
x6 = 0x00007ff8b4129000 NlsAnsiCodePage + 26720
x7 = 0x5d4b1dcd6d097720
x8 = 0x00007ff738e66000 __start_.objcrt$CAL
x9 = 0x0000000000000000
x10 = 0x000000007ffe0380
x11 = 0x0000000000000000
x12 = 0x0000000000000000
x13 = 0xa2e64eada2e64ead
x14 = 0x0000000000000001
x15 = 0x0000000000000070
x16 = 0x0000000080000001
x17 = 0x00005859193355a3
x18 = 0x000000e233970000
x19 = 0x00007ff857942570 gnustep-base-1_29.dll`NSLog at NSLog.m:293
x20 = 0x000002a841621080
x21 = 0x0000000000000000
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000e233affd30
lr = 0x00007ff738e61034 crash.exe`main + 40 at crash.mm:27
sp = 0x000000e233affd10
pc = 0x00007ff738e61048 crash.exe`main + 60 at crash.mm:27
cpsr = 0x80000000
(lldb)
Ubuntu 23.10 aarch64
Clang Version
Ubuntu clang version 18.1.3 (++20240322073236+ef6d1ec07c69-1~exp1~20240322193248.98)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Build Command
clang-18 ObjcCXXObjectReturnTest.mm -o ObjcCXXObjectReturnTest -g `gnustep-config --objc-flags` `gnustep-config --base-libs` -Xclang -fobjc-dispatch-method=non-legacy -fuse-ld=lld-18
* thread #1, name = 'ObjcCXXObjectRe', stop reason = breakpoint 2.1
frame #0: 0x0000aaaaaaab0dcc ObjcCXXObjectReturnTest`main(argc=<unavailable>, argv=<unavailable>) at ObjcCXXObjectReturnTest.mm:27:14
24 {
25 NSLog(@"Hello");
26
-> 27 auto pair = [Test bar]; // crashes
28
29 NSLog(@"Success");
30
(lldb) di
ObjcCXXObjectReturnTest`main:
0xaaaaaaab0d9c <+0>: stp x29, x30, [sp, #-0x10]!
0xaaaaaaab0da0 <+4>: mov x29, sp
0xaaaaaaab0da4 <+8>: mov x0, #0x2c ; =44
0xaaaaaaab0da8 <+12>: movk x0, #0xe000, lsl #16
0xaaaaaaab0dac <+16>: movk x0, #0x66cd, lsl #32
0xaaaaaaab0db0 <+20>: movk x0, #0x9197, lsl #48
0xaaaaaaab0db4 <+24>: bl 0xaaaaaaab0e90 ; symbol stub for: NSLog
0xaaaaaaab0db8 <+28>: adrp x8, 17
0xaaaaaaab0dbc <+32>: nop
0xaaaaaaab0dc0 <+36>: adr x1, 0xaaaaaaad12b0 ; ObjcCXXObjectReturnTest.PT_LOAD[3].__objc_selectors + 0
0xaaaaaaab0dc4 <+40>: ldr x8, [x8, #0xd0]
0xaaaaaaab0dc8 <+44>: ldr x0, [x8]
-> 0xaaaaaaab0dcc <+48>: bl 0xaaaaaaab0ea0 ; symbol stub for: objc_msgSend
0xaaaaaaab0dd0 <+52>: mov x0, #0x803c ; =32828
0xaaaaaaab0dd4 <+56>: movk x0, #0xbcf9, lsl #16
0xaaaaaaab0dd8 <+60>: movk x0, #0x1e3c, lsl #32
0xaaaaaaab0ddc <+64>: movk x0, #0xa7d7, lsl #48
0xaaaaaaab0de0 <+68>: bl 0xaaaaaaab0e90 ; symbol stub for: NSLog
0xaaaaaaab0de4 <+72>: mov w0, wzr
0xaaaaaaab0de8 <+76>: ldp x29, x30, [sp], #0x10
0xaaaaaaab0dec <+80>: ret
(lldb) register read
General Purpose Registers:
x0 = 0x0000aaaaaaad11a0 ._OBJC_CLASS_Test
x1 = 0x0000aaaaaaad12b0 ObjcCXXObjectReturnTest.PT_LOAD[3].__objc_selectors + 0
x2 = 0x0000000000000007
x3 = 0x0000aaaaaaad2010
x4 = 0x0000000000000004
x5 = 0x0000aaaaaaebc7f0
x6 = 0xb3c97132ac52cb5b
x7 = 0x0000fffff7e1f3a8 ._OBJC_CLASS_GSMutableString
x8 = 0x0000aaaaaaad12d0 ObjcCXXObjectReturnTest`._OBJC_REF_CLASS_Test
x9 = 0x0000000000000000
x10 = 0x0000fffff7f884cc libobjc.so.4.6`objc_slot_lookup_super2 + 264
x11 = 0x0000000000000003
x12 = 0x0000fffff7f87bd0 libobjc.so.4.6`objc_msg_lookup_sender + 100
x13 = 0x0000000000000003
x14 = 0x000000000042a2d5
x15 = 0x0000ffffffff8b88
x16 = 0x0000fffff7fb00d0
x17 = 0x0000fffff76d47f0 libc.so.6`free
x18 = 0x0000000000000034
x19 = 0x0000fffffffff0d8
x20 = 0x0000000000000001
x21 = 0x0000aaaaaaac0ed8
x22 = 0x0000aaaaaaab0d9c ObjcCXXObjectReturnTest`main at ObjcCXXObjectReturnTest.mm:24
x23 = 0x0000fffffffff0e8
x24 = 0x0000fffff7ffdb90 ld-linux-aarch64.so.1`_rtld_global_ro
x25 = 0x0000000000000000
x26 = 0x0000fffff7ffe008 _rtld_global
x27 = 0x0000aaaaaaac0ed8
x28 = 0x0000000000000000
fp = 0x0000ffffffffef50
lr = 0x0000aaaaaaab0db8 ObjcCXXObjectReturnTest`main + 28 at ObjcCXXObjectReturnTest.mm:27:14
sp = 0x0000ffffffffef50
pc = 0x0000aaaaaaab0dcc ObjcCXXObjectReturnTest`main + 48 at ObjcCXXObjectReturnTest.mm:27:14
cpsr = 0x40001000
Metadata
Metadata
Assignees
Type
Projects
Status
Done