XNU / Darwin内核中的setjmp / longjmp

时间:2016-05-15 15:39:44

标签: macos kernel-extension longjmp setjmp xnu

我在OS X的longjmp文件中需要setjmp / .kext。不幸的是,我认为在XNU中没有任何官方支持这些功能。有什么根本原因导致它无法正常工作,或者它现在还没有实施?

我有什么想法可以让它发挥作用吗?

如果有帮助,我想尝试让Lua在OS X内核中运行,但运行时似乎依赖于longjmp / setjmp或C ++异常,这两种情况都不可用于XNU。

1 个答案:

答案 0 :(得分:1)

没有任何关于标准兼容的setjmp / longjmp使用会阻止你在内核上下文中使用它。关于内核执行上下文要注意的主要事情是当前线程通常通过当前堆栈指针上的指针算法来识别,因此与用户空间不同,您不能使用绿色线程或以其他方式弄乱rsp寄存器(在x86-64)。 longjmp确实设置了堆栈指针,但只设置了之前由setjmp保存的值,如果你坚持使用标准,它将在同一个堆栈中,这样就安全了。

据我所知,编译器不会特别处理setjmp()调用,因此您可以很容易地在汇编语言中实现自己的版本。 Setjmp需要将返回指针,堆栈指针和任何被调用者保存的寄存器保存到传递给函数的jmp_buf类型数组中;所有这些都在相关平台的ABI中定义(在OS X的情况下为x86-64 sysv)。然后返回0(在x86-64上将rax设置为0)。您的longjmp版本只需要恢复此数组的内容并返回到保存的位置,并将传入的值作为返回值(将参数复制到x86-64上的rax)。要符合标准,如果0传递给longjmp,则必须返回1。

在用户空间中,setjmp / longjmp通常也会影响信号掩码,但不适用于内核。