苹果硅arm64环境下jmp_buf中存放了哪些寄存器?

问题描述 投票:0回答:1

我想在我的 Apple Silicon Macbook 中编写一个原生协程。由于原生协程需要

jmp_buf
中的
setjmp.h
,我试图找出
jmp_buf
中存储了哪些寄存器。

当我跳进

setjmp.h
中的
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/include/setjmp.h
文件时,我刚刚找到了代码,但看起来有点奇怪。

代码是:

/*
 * _JBLEN is the number of ints required to save the following:
 * r21-r29, sp, fp, lr == 12 registers, 8 bytes each. d8-d15
 * are another 8 registers, each 8 bytes long. (aapcs64 specifies
 * that only 64-bit versions of FP registers need to be saved).
 * Finally, two 8-byte fields for signal handling purposes.
 */
#define _JBLEN      ((14 + 8 + 2) * 2)

typedef int jmp_buf[_JBLEN];
typedef int sigjmp_buf[_JBLEN + 1];

#else
#   error Undefined platform for setjmp
#endif

_JBLEN
似乎定义了14 + 8个寄存器,但注释说是12 + 8。正如其他帖子所说,在arm64 arch中,x19-x28是被调用者保存的寄存器,应该保存,x29(fp)、x30(lr)、x31(sp)、pc也应该保存。在这种情况下,14 个寄存器似乎是有意义的。是评论错误还是我的计算错误?

我希望有人能帮我弄清楚jmp_buf中到底保存了哪些寄存器,如果MacOSX sdk的注释有误,我希望有人能帮忙纠正。

c macos apple-m1 arm64 setjmp
1个回答
0
投票

该评论显然是错误的,因为它漏掉了

x19
x20
,并且提到了
x29
fp
,它们是同一个。

以下是 ABI 声明的被调用者保存的内容:

  • x19
    x30
    (包括
    x29
    =
    fp
    x0
    =
    lr
  • q8
    q15
    的低64位,即
    d8
    -
    d15
  • sp

保存

pc
没有意义,因为你知道当前正在从哪里执行。所以你真的需要
13 + 8

现在,Apple 的源转储确实包含

setjmp
的实现,但该源转储是一个谎言,因为生产中使用的 实际 实现使用指针身份验证,并且到目前为止是闭源的。我可以把它的反汇编交给你,但我认为这是一个坏主意。
jmp_buf
被声明为不透明 blob 的全部原因是因为它的布局是私有的,并且允许更改
setjmp
longjmp
的实现。

如果您需要修改

jmp_buf
的能力,那么您最好编写自己的汇编例程来溢出/重新加载被调用者保存的寄存器。

© www.soinside.com 2019 - 2024. All rights reserved.