2016-05-15 30 views
2

我需要longjmp/setjmp在OS X的.kext文件中。不幸的是,我不认为XNU中有这些函数的官方支持。有没有什么根本的原因,为什么这不起作用,或者它现在只是没有实施?XNU/Darwin内核中的setjmp/longjmp

任何想法,我可以得到这个工作?

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

回答

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通常也会影响信号掩码,该信号掩码不适用于内核。

+0

由于一些巧合,我正在研究将“ZFS通道程序”移植到OSX ZFS实现中,该实现将lua加载到内核中,所以我也对结论感兴趣。目前它加载没有throw()能力的lua,但这显然是不可取的。 – lundman