链接程序和库指南

x86: 局部动态 (Local Dynamic, LD)

此代码序列实现线程局部存储的访问模型中介绍的 LD 模型。

表 8–9 32 位 x86: 局部动态线程局部变量的访问代码

代码序列

初始重定位

符号

0x00 leal  x1@tlsldm(%ebx), %eax

0x06 call  x1@tlsldmplt



# %eax - contains address of TLS block of current object



0x10 leal  x1@dtpoff(%eax), %edx



# %edx - contains address of local TLS variable x1



0x20 leal  x2@dtpoff(%eax), %edx



# %edx - contains address of local TLS variable x2
R_386_TLS_LDM

R_386_TLS_LDM_PLT

 

 

 

R_386_TLS_LDO_32

 

 

 

R_386_TLS_LDO_32
x1

x1

 

 

 

x1

 

 

 

x2
 

未完成的重定位

符号

GOT[n]

GOT[n + 1]
R_386_TLS_DTPMOD32

<none>
x

第一个 leal 指令生成 R_386_TLS_LDM 重定位。此重定位指示链接编辑器在 GOT 中分配空间,以存储当前目标文件的 TLS_index 结构。链接编辑器通过将相对于 GOT 的偏移替换为新的链接表项来处理此重定位。

装入目标文件索引在运行前无法确定。因此,将创建 R_386_TLS_DTPMOD32 重定位,并在此结构的 ti_tlsoffset 字段中填充零。call 指令使用 R_386_TLS_LDM_PLT 重定位标记。

在链接编辑时将确定每个局部符号的 TLS 偏移,因此链接编辑器将直接填充这些值。

当一个过程引用多个局部符号时,编译器将生成一次获取 TLS 块的基本地址的代码。然后,使用此基本地址计算每个符号的地址,而不需要单独调用库。