Linux AMD64中使用的fs / gs寄存器如何?

x86-64架构上,两个寄存器有一个特殊用途:FS和GS。 在linux 2.6。*中,FS寄存器似乎被用来存储线程本地信息。

  • 那是对的吗?
  • 什么是存储在FS:0? 有没有描述这个内容的C结构?
  • 什么是GS的使用?

Solutions Collecting From Web of "Linux AMD64中使用的fs / gs寄存器如何?"

在x86-64中有3个TLS条目 ,其中两个可通过FS和GS访问 ,FS由glibc内部使用(在IA32中, FS由Wine和GS由glibc使用 )。

Glibc使它的TLS入口指向一个包含一些线程内部结构的struct pthread 。 Glibc通常引用一个struct pthread变量作为pd ,大概是pthread描述符

在x86-64上, struct pthreadtcbhead_t开始(这取决于体系结构,参见宏TLS_DTV_AT_TPTLS_TCB_AT_TP )。 这个线程控制块头,AFAIU,包含一些即使有一个单一的线程所需要的字段。 DTV是动态线程向量,包含指向通过dlopen()加载的DSO的TLS块的指针。 在TCB之前或之后,在(程序)加载时链接的可执行文件和DSO都有一个静态TLS块。 TCB和DTV在Ulrich Drepper的TLS文档中有很好的解释(查看第3章中的图)。

要真正回答你的fs:0问题:x86_64 ABI要求fs:0包含fs自己指向的地址。 也就是说, fs:-4加载存储在fs:0 - 4 。 这个特性是必须的,因为你不能通过内核代码很容易得到fs指向的地址。 使地址存储在fs:0从而使线程本地存储的工作效率更高。

当你获得一个线程局部变量的地址时,你可以看到这个动作:

 static __thread int test = 0; int *f(void) { return &test; } int g(void) { return test; } 

编译

 f: movq %fs:0, %rax leaq -4(%rax), %rax retq g: movl %fs:-4, %eax retq 

i686做同样的,但%gs 。 在aarch64上,这是不必要的,因为地址可以从tls寄存器中读取。