2011-07-07 41 views
23

在x86-64架构上,两个寄存器有一个特殊用途:FS和GS。在linux 2.6。*中,FS寄存器似乎被用来存储线程本地信息。Linux AMD64中使用的fs/gs寄存器如何?

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

回答

28

在x86-64的有3 TLS entries,经由FS and GS入店其中的两个,FS由glibc的内部使用(在IA32显然FS is used by Wine and GS by 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之前或之后,有一个静态TLS块,用于在(程序)加载时链接的可执行文件和DSO。 TCB和DTV在Ulrich Drepper's TLS document中有相当好的解释(查看第3章中的图表)。

+1

FS被x86上的win32用来指向windows线程信息 - wine与之相匹配。 –

10

实际回答你的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寄存器本身读取。

相关问题