Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

线程局部存储的访问模型

每个 TLS 引用都遵循下列访问模型之一。这些模型按照最常见、但最少优化到速度最快、但限制最大的顺序列出。

常规动态 (General Dynamic, GD)-动态 TLS

此模型允许从共享目标文件或动态可执行文件中引用所有 TLS 变量。如果是第一次从特定线程引用 TLS 块,此模型还支持延迟分配此块。

局部动态 (Local Dynamic, LD)-局部符号的动态 TLS

此模型是对 GD 模型的优化。编译器可能会确定变量在要生成的目标文件中是局部绑定或受到保护的。在这种情况下,编译器将指示链接编辑器静态绑定动态的 tlsoffset 并使用此模型。与 GD 模型相比,此模型可提供更好的性能。每个函数只需要调用一次 tls_get_addr() 即可确定 dtv0,m 的地址。进行链接编辑时绑定的动态 TLS 偏移会与每个引用的 dtv0,m 地址相加。

初始可执行 (Initial Executable, IE)-具有指定偏移的静态 TLS

此模型只能引用初始静态 TLS 中包含的 TLS 变量。此模板由进程启动时可用的所有 TLS 块和一个小的备份预留空间组成。请参见程序启动。在此模型中,给定变量 x 相对于线程指针的偏移存储在 xGOT 项中。

此模型可以从初始进程启动后通过延迟装入、过滤器或 dlopen(3C) 装入的共享库中引用有限数量的 TLS 变量。该访问可通过固定的备份预留空间来实现。此预留空间只能为未初始化的 TLS 数据项提供存储空间。为实现最大的灵活性,共享目标文件应使用动态的 TLS 模型引用线程局部变量。


注 - 可以使用过滤器动态选择所使用的静态 TLS。共享目标文件可以生成为使用动态 TLS,并在生成使用静态 TLS 的对应共享目标文件时,充当辅助过滤器。如果资源允许装入静态 TLS 目标文件,将使用该库。否则,将回退到动态 TLS 目标文件,以确保共享目标文件提供的功能总是可用。有关过滤器的更多信息,请参见作为过滤器的共享目标文件
局部可执行 (Local Executable, LE)-静态 TLS

此模型只能引用动态可执行文件的 TLS 块中包含的 TLS 变量。链接编辑器静态地计算相对于线程指针的偏移,而不需要进行动态重定位或额外引用 GOT。此模型不能用于引用动态可执行文件外部的变量。

链接编辑器可以将代码从更常规的访问模型转换为更优化的模型(如果确定适合进行转换)。这种转换可以使用独特的 TLS 重定位来实现。这些重定位不仅请求执行更新,还会标识要使用的 TLS 访问模型。

链接编辑器在了解 TLS 访问模型和要创建的目标文件类型后,便可执行转换。例如,如果一个可重定位目标文件使用 GD 访问模型,被链接到一个动态可执行文件中。在这种情况下,链接编辑器可以适当地使用 IELE 访问模型转换引用。然后执行模型所需的重定位。

下图说明了不同的访问模型,以及从一个模型到另一个模型的转换。

图 14-2  线程局部存储的访问模型和转换

image:线程局部存储的访问模型和转换