I need longjmp
/setjmp
in a .kext
file for OS X. Unfortunately, I don't think there's any official support for these functions in XNU. Is there any fundamental reason why this cannot work or is it just not implemented right now?
Any ideas how I could get this to work?
If it helps, I want to try to get Lua to run in the OS X kernel but the runtime seems to depend on either longjmp
/setjmp
or C++ exceptions both of which are not available in XNU.
There's nothing about standard-compliant use of setjmp/longjmp which stops you from using it in a kernel context. The main thing to be careful about regarding the kernel execution context is that the current thread is usually identified via pointer arithmetic on the current stack pointer, so unlike in user space, you can't use green threads or otherwise mess with the rsp register (on x86-64). longjmp does set the stack pointer, but only to the value previously saved by setjmp, which will be in the same stack if you stick to standard use, so that's safe.
As far as I'm aware, compilers don't treat setjmp() calls specially, so you can implement your own version quite easily as a function in assembly language. Setjmp will need to save the return pointer, the stack pointer, and any callee-saved registers to the jmp_buf-typed array passed into the function; all of this is defined in the ABI for the platform in question (x86-64 sysv in the case of OS X). Then return 0 (set rax to 0 on x86-64). Your version of longjmp will simply need to restore the contents of this array and return to the saved location, with the passed-in value as the return value (copy the argument to rax on x86-64). To comply with the standard, you must return 1 if 0 is passed to longjmp.
In userspace, setjmp/longjmp typically also affect the signal mask, which doesn't apply in the kernel.