Why does Objective-C IMP crash when called directly on macOS ARM64e? #180545
-
BodyI’m doing a small macOS ARM64 runtime experiment. Example: Method m = class_getInstanceMethod([MyClass class], @selector(test));
IMP fn = method_getImplementation(m);
printf("%p\n", fn);But calling it manually: ((void(*)(id, SEL))fn)(obj, @selector(test));instantly crashes with: The object, selector, and IMP address are all correct. Why does directly calling the IMP pointer only crash on macOS ARM64e? Guidelines
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
On macOS ARM64e, Objective‑C IMPs are entered through code that expects a PAC‑authenticated LR (x30). As soon as the function prologue/epilogue checks LR, the PAC authentication fails → Why normal calls work: |
Beta Was this translation helpful? Give feedback.
On macOS ARM64e, Objective‑C IMPs are entered through code that expects a PAC‑authenticated LR (x30).
When you call the IMP manually like a normal function pointer, you skip the ObjC dispatcher, so LR is not signed the way the IMP expects.
As soon as the function prologue/epilogue checks LR, the PAC authentication fails →
macOS raises:
EXC_BAD_ACCESS (invalid PAC)
Why normal calls work:
[obj test] routes through objc_msgSend, which sets up a proper authenticated frame.