链接程序和库指南

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

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

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

代码序列

初始重定位

符号

0x00 .byte 0x66

0x01 leaq  x@tlsgd(%rip), %rdi

0x08 .word 0x666

0x0a rex64

0x0b call  __tls_get_addr@plt



# %iax - contains address of TLS variable
<none>

R_AMD64_TLSGD

<none>

<none>

R_AMD64_PLT32
 

x





__tls_get_addr
 

未完成的重定位

符号

GOT[n]

GOT[n + 1]
R_AMD64_DTPMOD64

R_AMD64_DTPOFF64
x

x

__tls_get_addr() 函数采用单个参数,即 tls_index 结构的地址。与 x@tlsgd(%rip) 表达式关联的 R_AMD64_TLSGD 重定位指示链接编辑器在 GOT 中分配 tls_index 结构。tls_index 结构所需的两个元素将保留在连续的 GOT 项(GOT[n]GOT[n+1])中。这些 GOT 项与 R_AMD64_DTPMOD64R_AMD64_DTPOFF64 重定位关联。

地址 0x00 处的指令计算第一个 GOT 项的地址。此计算将 GOT 起始位置的 PC 相对地址(在链接编辑时确定)与当前指令指针相加。使用 %rdi 寄存器将结果传递给 __tls_get_addr() 函数。


注 –

leaq 指令计算第一个 GOT 项的地址。将 GOT 的 PC 相对地址(在链接编辑时确定)与当前指令指针相加来执行此计算。.byte.word.rex64 前缀确保整个指令序列占用 16 字节。由于这些前缀不会对代码造成负面影响,因此可以使用这些前缀。