Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux上,TLS是由内核还是由libc(或其他语言运行时)设置的?_C_Linux_Libc_Thread Local Storage - Fatal编程技术网

在Linux上,TLS是由内核还是由libc(或其他语言运行时)设置的?

在Linux上,TLS是由内核还是由libc(或其他语言运行时)设置的?,c,linux,libc,thread-local-storage,C,Linux,Libc,Thread Local Storage,我只是在研究如何在Linux系统上实现TLS(线程本地存储)。该文档解释了如何将程序对线程局部变量的要求编码为ELF二进制文件,以及“运行时”应如何处理此类二进制文件 但是,我不清楚设置TLS区域的“运行时”实际上是Linux内核(及其加载ELF二进制文件的代码)还是libc中的一些初始化代码。有人能简单解释一下吗 (背景:我试图静态链接并运行一个应用程序,但它在启动时会出现segfaults。在gdb中,我可以看到segfaulting代码是libc的一些init代码。它试图使用相对于GS的地

我只是在研究如何在Linux系统上实现TLS(线程本地存储)。该文档解释了如何将程序对线程局部变量的要求编码为ELF二进制文件,以及“运行时”应如何处理此类二进制文件

但是,我不清楚设置TLS区域的“运行时”实际上是Linux内核(及其加载ELF二进制文件的代码)还是libc中的一些初始化代码。有人能简单解释一下吗


(背景:我试图静态链接并运行一个应用程序,但它在启动时会出现segfaults。在gdb中,我可以看到segfaulting代码是libc的一些init代码。它试图使用相对于GS的地址读取一个静态变量,但GS是零。)

线程本地存储初始化是libc提供的启动代码的一部分。静态链接时,链接器应将TLS初始化添加到链接到程序的启动代码中

例如,glibc在
libc.a
中有
\u libc\u setup\u tls
\u dl\u tls\u setup
(以及其他相关内容),如果您通过
gcc-static
链接,它将添加到程序的初始化代码中。(对于动态链接的程序,
\u dl
…函数是ELF动态链接器加载程序的一部分,
ld linux.so
,它不用于运行静态链接的程序。)

因此,在静态链接的可执行文件中正确初始化TLS是C库(提供代码)和工具链(必须了解如何正确链接所有必要的启动代码)之间协作的结果


内核参与TLS初始化的程度很小。(基本上,它只需确保libc可以使用
.tdata
部分进行初始化)有关详细信息,请参阅。

glibc和musl是开源的;您可以查看源代码。您讨论的是TLS(线程本地存储)还是TLS(传输层安全)?内容:本地存储;tag建议使用后者。你是同义词吗?我已经删除并添加了,但显然没有映射到。@JonathanLeffler,我添加了tls,意思是线程本地存储。谢谢你纠正错误。我已经检查过了;是的同义词。这并没有回答有关如何设置GS段以指向TLS段的关键问题。这是只有内核才能做到的。我还没有研究glibc,但我只是检查了musl。它在启动时初始化TLS(如您所说),但随后还使用
set\u thread\u area
syscall在进程的LDT中创建一个条目,该条目指向为TLS分配的空间。然后libc设置
%gs
寄存器,以便它引用TLS的LDT条目。(这在x86-32上--x86-64使用不同的段寄存器。)