在x86-64架构上,两个寄存器有一个特殊用途:FS和GS。 在linux 2.6。*中,FS寄存器似乎被用来存储线程本地信息。
那是对的吗?
什么是存储在FS:0? 有没有描述这个内容的C结构?
什么是GS的使用?
如何使用npm在64位系统上构build32位二进制文件?
基于插件架构的c / c ++应用程序
Nginx和apache web服务器
在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 pthread从tcbhead_t开始(这取决于体系结构,参见宏TLS_DTV_AT_TP和TLS_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寄存器中读取。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。