我正在裸露的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
寄存器是否需要更多步骤?
这里的代码生成是根据系统V ABI的,如Ross在评论中提到的。ABI要求将%fs:0
设置为%fs
itself的值。
因此,在这里,将地址0xffffc00000002000
的值设置为0xffffc00000002000
即可满足ABI并按预期使用FsBase。
换句话说,mov %fs:0x0, %rax
试图访问FsBase
处的值,而不是0x0
处的值。 FsBase的值恰好是0。