setjmp/longjmp 在 XNU/Darwin 内核中

setjmp/longjmp in XNU/Darwin Kernel

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

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

如果有帮助,我想尝试在 OS X 内核中将 Lua 变为 运行 但 运行 时间似乎取决于 longjmp/setjmp 或 C++ 异常在 XNU 中均不可用。

setjmp/longjmp 的符合标准的使用不会阻止您在内核上下文中使用它。关于内核执行上下文的主要注意事项是当前线程通常通过当前堆栈指针上的指针算法来识别,因此与用户 space 不同,您不能使用绿色线程或以其他方式混淆rsp 寄存器(在 x86-64 上)。 longjmp 确实设置了堆栈指针,但仅设置为之前由 setjmp 保存的值,如果您坚持标准使用,它将位于同一堆栈中,所以这是安全的。

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

在用户space中,setjmp/longjmp通常也会影响信号掩码,这在内核中不适用。