链接程序和库指南

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

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

表 8–3 SPARC: 局部动态线程局部变量的访问代码

代码序列

初始重定位

符号

# %l7 - initialized to GOT pointer



0x00 sethi %hi(@tmndx(x1)), %o0

0x04 add   %o0, %lo(@tmndx(x1)), %o0

0x08 add   %l7, %o0, %o0

0x0c call  x@TLSPLT



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



0x10 sethi %hi(@dtpoff(x1)), %l1

0x14 xor   %l1, %lo(@dtpoff(x1)), %l1

0x18 add   %o0, %l1, %l1



# %l1 - contains address of local TLS variable x1



0x20 sethi %hi(@dtpoff(x2)), %l2

0x24 xor   %l2, %lo(@dtpoff(x2)), %l2

0x28 add   %o0, %l2, %l2



# %l2 - contains address of local TLS variable x2
 

 

R_SPARC_TLS_LDM_HI22

R_SPARC_TLS_LDM_LO10

R_SPARC_TLS_LDM_ADD

R_SPARC_TLS_LDM_CALL

 

 

 

R_SPARC_TLS_LDO_HIX22

R_SPARC_TLS_LDO_LOX10

R_SPARC_TLS_LDO_ADD

 

 

 

R_SPARC_TLS_LDO_HIX22

R_SPARC_TLS_LDO_LOX10

R_SPARC_TLS_LDO_ADD
 

 

x1

x1

x1

x1

 

 

 

x1

x1

x1

 

 

 

x2

x2

x2
 

未完成的重定位: 32 位

符号

GOT[n]

GOT[n + 1]
R_SPARC_TLS_DTPMOD32

<none>
x1
 

未完成的重定位: 64 位

符号

GOT[n]

GOT[n + 1]
R_SPARC_TLS_DTPMOD64

<none>
x1

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

装入目标文件索引在运行前无法确定。因此,将创建 R_SPARC_TLS_DTPMOD32 重定位,并在 TLS_index 结构的 ti_tlsoffset 字段中填充零。

第二个 addcall 指令分别由 R_SPARC_TLS_LDM_ADDR_SPARC_TLS_LDM_CALL 重定位标记。

后面的 sethi 指令和 xor 指令分别生成 R_SPARC_LDO_HIX22R_SPARC_TLS_LDO_LOX10 重定位。在链接编辑时将确定每个局部符号的 TLS 偏移,因此将直接填充这些值。add 指令使用 R_SPARC_TLS_LDO_ADD 重定位标记。

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


注 –

包含 add 指令(由 R_SPARC_TLS_LDO_ADD 标记)中的 TLS 目标文件地址的寄存器必须是指令序列中的第一个寄存器。在代码变换期间,此要求允许链接编辑器标识寄存器。