AArch64 Linux 中的标记虚拟地址

作者:Will Deacon <will.deacon@arm.com>

日期:2013 年 6 月 12 日

本文档简要描述了 AArch64 转换系统中标记虚拟地址的规定以及它们在 AArch64 Linux 中的潜在用途。

内核配置转换表,使得通过 TTBR0(即用户空间映射)进行的转换忽略虚拟地址的最高字节(位 63:56)。这释放了这个字节供应用程序使用。

将标记地址传递给内核

内核对用户空间内存地址的所有解释都假定地址标记为 0x00,除非应用程序显式启用了 AArch64 标记地址 ABI(AArch64 标记地址 ABI)。

这包括但不限于以下位置找到的地址:

  • 系统调用的指针参数,包括传递给系统调用的结构体中的指针,

  • 堆栈指针 (sp),例如,在解释它以传递信号时,

  • 帧指针 (x29) 和帧记录,例如,在解释它们以生成回溯或调用图时。

当用户空间应用程序未启用 AArch64 标记地址 ABI 时,在任何这些位置使用非零地址标记可能会导致返回错误代码、引发(致命)信号或其他失败模式。

由于这些原因,当禁用 AArch64 标记地址 ABI 时,禁止通过系统调用将非零地址标记传递给内核,并且强烈建议不要对 sp 使用非零地址标记。

维护使用非零地址标记的帧指针和帧记录的程序可能会遭受调试和分析可见性受损或不准确的情况。

保留标记

在传递信号时,除非在安装信号处理程序时在 sigaction.sa_flags 中设置了标志 SA_EXPOSE_TAGBITS,否则非零标记不会保留在 siginfo.si_addr 中。这意味着,除非设置了该标志,否则使用标记的应用程序中的信号处理程序不能依赖于这些字段中维护的用户虚拟地址的标记信息。

由于架构限制,即使设置了 SA_EXPOSE_TAGBITS,在响应同步标记检查故障 (SEGV_MTESERR) 时,故障地址的位 63:60 也不会保留。应用程序应将这些位的值视为未定义,以便适应可能保留这些位的未来架构修订。

对于响应观察点调试异常而引发的信号,无论 SA_EXPOSE_TAGBITS 标志设置如何,标记信息都将被保留。

无论 SA_EXPOSE_TAGBITS 标志设置如何,非零标记永远不会保留在 sigcontext.fault_address 中。

该架构阻止使用标记的 PC,因此在异常返回时,高字节将设置为位 55 的符号扩展。

当启用 AArch64 标记地址 ABI 时,会保持此行为。

其他注意事项

使用标记指针时应特别小心,因为 C 编译器很可能不会对仅在高字节不同的两个虚拟地址进行危险处理。