链接程序和库指南

SPARC: 常规动态 (General Dynamic, GD)

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

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

代码序列

初始重定位

符号

# %l7 - initialized to GOT pointer



0x00 sethi %hi(@dtlndx(x)), %o0

0x04 add   %o0, %lo(@dtlndx(x)), %o0

0x08 add   %l7, %o0, %o0

0x0c call  x@TLSPLT



# %o0 - contains address of TLS variable
 

 

R_SPARC_TLS_GD_HI22

R_SPARC_TLS_GD_LO10

R_SPARC_TLS_GD_ADD

R_SPARC_TLS_GD_CALL
  

 

x

x

x

x
 

未完成的重定位: 32 位

符号

GOT[n]

GOT[n + 1]
R_SPARC_TLS_DTPMOD32

R_SPARC_TLS_DTPOFF32
x

x
 

未完成的重定位: 64 位

符号

GOT[n]

GOT[n + 1]
R_SPARC_TLS_DTPMOD64

R_SPARC_TLS_DTPOFF64
x

x

sethiadd 指令分别生成 R_SPARC_TLS_GD_HI22R_SPARC_TLS_GD_LO10 重定位。这些重定位指示链接编辑器在 GOT 中分配空间,以存储变量 xTLS_index 结构。链接编辑器通过将相对于 GOT 的偏移替换为新的 GOT 项来处理此重定位。

x 的装入目标文件索引和 TLS 块索引在运行前无法确定。因此,链接编辑器根据 GOT 放置 R_SPARC_TLS_DTPMOD32R_SPARC_TLS_DPTOFF32 重定位,以便运行时链接程序处理。

第二个 add 指令导致生成 R_SPARC_TLS_GD_ADD 重定位。仅当链接编辑器将 GD 代码序列更改为另一个序列时,才使用此重定位。

call 指令使用特殊语法 x@TLSPLT。此调用引用 TLS 变量并生成 R_SPARC_TLS_GD_CALL 重定位。此重定位指示链接编辑器将调用绑定到 __tls_get_addr() 函数,并将 call 指令与 GD 代码序列关联。


注 –

add 指令必须出现在 call 指令前面。不能将 add 指令放在调用的延迟槽中。由于后面进行的代码变换需要已知顺序,所以必须满足此要求。

用作 add 指令(由 R_SPARC_TLS_GD_ADD 重定位标记)的 GOT 指针的寄存器必须是 add 指令中的第一个寄存器。在代码变换期间,此要求允许链接编辑器标识 GOT 指针寄存器。