【问题标题】:setjmp/longjmp in XNU/Darwin KernelXNU/Darwin 内核中的 setjmp/longjmp
【发布时间】:2016-05-15 15:39:44
【问题描述】:

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

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

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

【问题讨论】:

    标签: macos kernel-extension setjmp 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 通常也会影响信号掩码,这不适用于内核。

    【讨论】:

    • 巧合的是,我正在考虑将“ZFS 通道程序”移植到 OSX ZFS 实现,它将 lua 加载到内核中,所以我也对这个结论感兴趣。目前它加载没有 throw() 功能的 lua,但这显然是不可取的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 2016-03-22
    • 1970-01-01
    相关资源
    最近更新 更多