在Linux上,是由内核还是由libc(或其他语言运行库)设置TLS?
我只是研究如何在Linux系统上实现TLS(线程本地存储)。 文档ELF用于线程本地存储的处理解释了如何将程序对线程局部变量的需求编码到ELF二进制文件中,以及“运行时”如何处理这些二进制文件。
然而,我不清楚在实际中,设置TLS区域的“运行时”是Linux内核(以及它的用于加载ELF二进制文件的代码)还是libc中的一些初始化代码。 有人可以简单解释吗?
(背景:我试图静态链接并运行一个应用程序,但它在启动时发生段错误,在gdb中,我可以看到segfaulting代码是libc中的一些init代码,它试图使用相对于GS,但GS为零。)
线程本地存储初始化是libc提供的启动代码的一部分。 静态链接时,链接器应将TLS初始化添加到链接到程序中的启动代码中。
例如,glibc的有__libc_setup_tls
和_dl_tls_setup
(以及其他相关事物)中libc.a
,如果通过,也就是说,链接将被添加到您的程序的初始化代码gcc -static
。 (对于动态链接的程序, _dl_
...函数是ELF动态链接程序加载程序ld-linux.so
,它不用于运行静态链接的程序。)
因此,静态链接可执行文件中正确的TLS初始化是您的C库(提供代码)和您的工具链(必须了解如何正确链接所有必需的启动代码)之间的协作结果。
内核参与TLS初始化很小。 (基本上,它只需确保.tdata
部分可供libc进行初始化。)有关详细信息,请参阅ELF文件TLS和LOAD程序部分。
上一篇: On Linux, is TLS set up by the kernel or by libc (or other language runtime)?
下一篇: SQL Query Using Entity Framework Runs Slower, uses bad query plan