首页 文章

XNU / Darwin内核中的setjmp / longjmp

提问于
浏览
2

我在OS X的 .kext 文件中需要 longjmp / setjmp . 不幸的是,我在XNU中对这些功能没有任何官方支持 . 有什么根本原因可以解决这个问题,或者它现在还没有实施?

任何想法我怎么能让这个工作?

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

1 回答

  • 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通常也会影响信号掩码,这在内核中不适用 .

相关问题