ZHCADC4A September 2011 – March 2014
TLS 的默认代码生成应适用于静态可执行文件和裸机动态链接。对于静态可执行文件,请使用 TPR 寻址生成以下寻址:
CALLP __c6xabi_get_tp() ; Returns TP in A4. Can be CSEed.
MVK $TPR_byte(x), B4 ; reloc R_C6000_TPR_U15_B
LDB *A4[B4], A4 ; A4 contains the value of thread-local char x
默认情况下为裸机动态链接生成的代码可假设所有模块都是初始加载的。这意味着线程局部变量的偏移量是动态链接时常量,如 图 7-3 所示。因此,可使用 TPR 寻址。唯一的区别是,在裸机动态链接的情况下,需要 64 位 TCB 以使代码兼容今后的任何 dlopen() 支持。对于静态可执行文件,不存在 TCB。TPR 寻址仍可用于这两种模型。对于静态可执行文件,静态链接器将使用大小为零的 TCB,对于裸机动态链接,将使用大小为 64 位的 TCB。
如上所述,最初加载的模块是连续放置的,可执行文件的 TLS 块位于 TCB 之后。在这种情况下,可使用来自 TP 的静态链接时间常量偏移量来访问可执行文件中的变量。可使用来自 TP 的动态链接时间常量偏移量来访问动态库中定义的变量。
生成该寻址后,模块标记为 DF_STATIC_TLS。
构建动态可执行文件时,静态链接器将可执行文件(自带数据)中定义符号的 TPR 重定位解析为 TP 偏移量。如果导入符号,则会复制重定位到动态重定位表,以便动态加载器进行解析。构建动态库时,会将 TPR 重定位复制到动态重定位表中。
裸机中的线程局部访问会导致代码区段中的动态重定位。这意味着得到的模块不是真正的 PIC(与位置无关的代码)。TI 编译器支持具有 --gen_pic 选项的裸机 PIC。使用该选项时,应从 GOT 条目访问 TPR 偏移量,以便生成与位置无关的代码。