Ale*_*x D 8 c linux libc thread-local-storage
我正在研究如何在Linux系统上实现TLS(线程本地存储).文档ELF处理线程局部存储解释了程序对线程局部变量的要求如何在ELF二进制文件中编码,以及"运行时"如何处理这些二进制文件.
但是,我不清楚在实践中,设置TLS区域的"运行时"是Linux内核(及其加载ELF二进制文件的代码)还是libc中的一些初始化代码.有人能简单解释一下吗
(背景:我正在尝试静态链接并运行一个应用程序,但它在启动时会出现段错误.在gdb中,我可以看到segfaulting代码是来自libc的一些初始化代码.它试图使用相对于的地址读取静态变量GS,但GS为零.)
小智 5
线程本地存储初始化是 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 程序部分。