Cannot run kext built on 10.11

When I build a kext that uses IOLockSleepDeadline and IOLockWakeup with Xcode 7 with the MacOSX10.11.sdk, the resulting kext will not load on OS X 10.8 (even though I am specifying MACOSX_DEPLOYMENT_TARGET=10.8 and -mmacosx-version-min=10.8).


Trying to load the resulting kext on 10.8 yeilds:

(kernel) kxld[com.mykext]: The following symbols are unresolved for this kext:
(kernel) kxld[com.mykext]: _IOLockSleepDeadline_darwin14
(kernel) kxld[com.mykext]: _IOLockWakeup_darwin14
(kernel) Can't load kext com.mykext - link failed.


It looks like by the very act of compiling against the 10.11 headers (particularly IOLocks.h), the "_darwin14" part is being appended.


However, building using Xcode 5.1.1 with MacOSX10.9.sdk, the resulting kext loads on both 10.8 and 10.11 without modifications.


In the 10.11 IOLocks.h, there are three definitions:

int IOLockSleep( IOLock * lock, void *event, UInt32 interType) __DARWIN14_ALIAS(IOLockSleep);
int IOLockSleepDeadline( IOLock * lock, void *event, AbsoluteTime deadline, UInt32 interType) __DARWIN14_ALIAS(IOLockSleepDeadline);
void IOLockWakeup(IOLock * lock, void *event, bool oneThread) __DARWIN14_ALIAS(IOLockWakeup);


And in the 10.8 IOLocks.h, the same definitions are:

int     IOLockSleep( IOLock * lock, void *event, UInt32 interType);
int     IOLockSleepDeadline( IOLock * lock, void *event, AbsoluteTime deadline, UInt32 interType);
void    IOLockWakeup(IOLock * lock, void *event, bool oneThread);


That is, the "__DARWIN14_ALIAS" macro is mangling the function names in the 10.11 headers. Where I'm explicitly compiling for 10.8 (darwin 12, if I'm understanding the numbering correctly), it doesn't surprise me that the _darwin14 variants of the functions don't exist in the 10.8 kernel.


What is the best way to approach this?

Accepted Reply

According to Apple one must build kernel extensions against the SDK for the lowest OS version they are to support. See WWDC 2013 session 707 "What's New in Kext Development". In your case this would be the 10.8 SDK. You were just lucky that the kext built with Xcode 5.1.1 and the 10.9 SDK worked on 10.8. The trick with setting the deployment target to a version lower than the SDK only works for userspace code. This makes things difficult for kernel developers that need to support older OS version since we are forced to use old Xcode versions, on old OS's, on old hardware, for developement.

Replies

According to Apple one must build kernel extensions against the SDK for the lowest OS version they are to support. See WWDC 2013 session 707 "What's New in Kext Development". In your case this would be the 10.8 SDK. You were just lucky that the kext built with Xcode 5.1.1 and the 10.9 SDK worked on 10.8. The trick with setting the deployment target to a version lower than the SDK only works for userspace code. This makes things difficult for kernel developers that need to support older OS version since we are forced to use old Xcode versions, on old OS's, on old hardware, for developement.

Bummer! I guess I'll be keeping an old version of Xcode around, then... Thanks!