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 编译器很可能不会对仅在最高字节中不同的两个虚拟地址进行哈希处理。