ELF Handling For Thread-Local Storage文档给出了各种体系结构的各种模型(本地执行/初始执行/一般动态)的汇编序列。但不是 ARM——在任何地方我都可以看到这样的 ARM 代码序列吗?我正在开发一个编译器,并希望生成能够与平台链接器(程序链接器和动态链接器)一起正常运行的代码。
为清楚起见,我们假设一个 ARMv7 CPU 和一个相当新的内核和 glibc(例如 3.13+/2.19+),但如果这很容易解释的话,我也会对旧硬件/软件必须更改的内容感兴趣。
最佳答案
我不太明白你想要什么。然而,汇编程序序列(针对 ARMv6+ 和一个有能力的内核)是,
mrc p15, 0, rX, c13, c0, 2 @ get the user r/w register
这在某些 ARM 手册中称为 TPIDRURW。您的 TLS 表/结构必须以此值(可能是指针)为父级。使用 mcr
速度更快,但如果您没有在 ELF 中设置 HWCAP_TLS
(可以在所有 ARM CPU 上使用),您也可以调用帮助程序(见下文) Linux 支持)。
地址 0xffff0fe8 的意图似乎是您可以使用这些 4 字节而不是直接使用上面的汇编器 (rX
== r0
) 因为它可能在某处的某些机器上有所不同。
这取决于 CPU 类型。有一个helper in the vector page @0xffff0fe0 in entry-armv.S ;如果硬件不支持,它在进程/线程结构中。文档在 kernel_user_helpers.txt 中
使用示例:
typedef void * (__kuser_get_tls_t)(void);
#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
void foo()
{
void *tls = __kuser_get_tls();
printf("TLS = %p\n", tls);
}
您执行系统调用来设置 TLS 内容。 clone
是一种设置线程上下文的方法。 thread_info持有线程的所有寄存器;它可能与其他 task_struct
共享一个 mm(内存管理或进程内存 View )。即,thread_info 为每个创建的线程都有一个 tp_value
。
Here is a dicussion ARM 的实现。 ELF/nptl/glibc 和 Linux 内核都涉及(和/或搜索术语以进行更多调查)。 get_tls()
的系统调用可能过于昂贵,当前的主线有一个矢量页面助手(由所有线程/进程映射)。
一些 glibc 源代码,tls-macros.h , tlsdesc.c等。完整/简洁的答案很可能取决于版本,
- 你的 ARM CPU。
- 您的 Linux 内核。
- 你的 glibc。
- 您的编译器(和标志!)。
关于linux - ARM 上 TLS 的代码序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29818269/