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

标签 c linux libc thread-local-storage

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

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

(背景:我正在尝试静态链接并运行应用程序,但它在启动时出现段错误。在 gdb 中,我可以看到段错误代码是来自 libc 的一些初始化代码。它正在尝试读取静态使用相对于 GS 的地址的变量,但 GS 为零。)

最佳答案

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

例如,glibc 在 libc.a 中有 __libc_setup_tls_dl_tls_setup (以及其他相关的东西),它们将被添加到如果您通过 gcc -static 进行链接,则程序的初始化代码。 (对于动态链接程序,_dl_... 函数是 ELF 动态链接器加载程序 ld-linux.so 的一部分,它不用于运行静态链接程序。)

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

内核很少参与 TLS 初始化。 (基本上,它只需要确保 .tdata 部分可用于 libc 进行初始化。)参见 ELF file TLS and LOAD program sections了解详情。

关于c - 在 Linux 上,TLS 是由内核还是由 libc(或其他语言运行时)设置的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30377020/

相关文章:

c - 尝试编译 xf86drm.h 示例

python - 在 Linux 上使用 cx_freeze 卡住共享对象

c - C 中使用 strtol 将二进制转换为 int

c++ - 在结构中为 Char* 赋值,哪种解决方案是理想的 c++

linux - 如何将我的 GTK 应用程序放在桌面菜单中?

linux - linux和windows之间的记录锁定问题

gcc - 使用 libc 库进行编译

c - 如何配置 Visual Studio 2010 以运行 GEGL 库?

c - 如何将无符号长整型拆分并重新组合为有符号短整型?

regex - 使用 sed 向后删除特定空格