x86-64 中的 `fs` 相对地址

`fs` relative address in x86-64

我正在尝试在 Rust 中的裸机上使用线程本地存储。我最初将 FsBase MSR 设置为目标值。再次读取 FsBase 寄存器和 gdb 中的 运行 info registers fs_base 也证实了这一点。

当我尝试读取线程局部变量时,rust 生成以下 asm 代码(从 gdb 反汇编)

mov    %fs:0x0,%rax
mov    -0x2000(%rax),%cl
mov    %cl,-0x189(%rbp)

当我尝试逐步执行这些指令时,我发现在指令 1 之后,%rax 的值保持为 0x0 而不是使用 FsBase 中的值。这不是预期的行为。

在我的例子中,FsBase 设置为 0xffffc00000002000。 运行 进入指令 3 后,cpu 引发页面错误异常,目标位置为 0xffffffffffffe000,这意味着该指令正尝试从 0x0 - 0x2000 而不是偏移量加载数据来自 0xffffc00000002000。这不是预期的行为。

实例化 fs 寄存器是否需要更多步骤?

这里的代码生成是根据 Ross 在评论中提到的 System V ABI。 ABI 要求 %fs:0 设置为 %fs itself.

的值

所以,在这里,将地址 0xffffc00000002000 的值设置为 0xffffc00000002000 满足 ABI 并按预期使用 FsBase。

换句话说,mov %fs:0x0, %rax 试图访问 FsBase 而不是 0x0 的值。 FsBase 的值刚好为 0。