我需要longjmp
/setjmp
在.kext
OS X 的文件中。不幸的是,我认为 XNU 中没有对这些功能的任何官方支持。是否有任何根本原因导致这无法正常工作,或者只是现在没有实施?
有什么想法可以让这个工作吗?
如果有帮助,我想尝试让 Lua 在 OS X 内核中运行,但运行时似乎依赖于longjmp
/setjmp
或 C++ 异常,这两种异常在 XNU 中都不可用。
我需要longjmp
/setjmp
在.kext
OS X 的文件中。不幸的是,我认为 XNU 中没有对这些功能的任何官方支持。是否有任何根本原因导致这无法正常工作,或者只是现在没有实施?
有什么想法可以让这个工作吗?
如果有帮助,我想尝试让 Lua 在 OS X 内核中运行,但运行时似乎依赖于longjmp
/setjmp
或 C++ 异常,这两种异常在 XNU 中都不可用。
符合标准的 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 通常也会影响信号掩码,这不适用于内核。