ARM 上 TLS 的代码序列

2023-12-19

The 线程本地存储的 ELF 处理 http://www.akkadia.org/drepper/tls.pdf文档给出了各种架构的各种模型(本地执行/初始执行/一般动态)的汇编序列。但 ARM 不行——有什么地方可以看到 ARM 的此类代码序列吗?我正在开发一个编译器,并希望生成能够与平台链接器(程序链接器和动态链接器)正常运行的代码。

为了清楚起见,我们假设一个 ARMv7 CPU 和一个相当新的内核和 glibc(比如 3.13+ / 2.19+),但我也对旧的硬件/软件必须改变什么感兴趣,如果这很容易解释的话。


我不太明白你想要什么。然而,汇编程序序列(对于 ARMv6+ 和有能力的内核)是,

mrc p15, 0, rX, c13, c0, 2  @ get the user r/w register

这就是所谓的TPIDRURW在一些ARM手册中。您的 TLS 表/结构必须以此值(可能是指针)作为父级。使用mcr更快,但如果你不设置,你也可以调用助手(见下文)HWCAP_TLS在你的 ELF 中(可以在 Linux 支持的所有 ARM CPU 上使用)。

地址0xffff0fe8的意图seems您可以使用这 4 个字节,而不是直接使用上面的汇编器 (rX == r0)因为某些地方的某些机器可能会有所不同。


它取决于 CPU 类型。有一个入口-armv.S 中向量页 @0xffff0fe0 中的帮助程序 https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/kernel/entry-armv.S?i#n1003;如果硬件不支持,则它位于进程/线程结构中。文档位于kernel_user_helpers.txt https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm/kernel_user_helpers.txt#n75

使用示例:

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是一种设置线程上下文的方法。这线程信息 https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/include/asm/thread_info.h保存线程的所有寄存器;它可能共享一个mm(内存管理或进程内存视图)与其他task_struct。即,thread_info 有一个tp_value对于每个创建的线程。

这里有一个讨论 http://www.redhat.com/archives/phil-list/2003-May/msg00054.htmlARM 实现。 ELF/nptl/glibc 和 Linux 内核都涉及(和/或搜索术语以进行更多调查)。系统调用为get_tls()可能太昂贵了,当前的主线有一个向量页助手(由所有线程/进程映射)。

一些 glibc 源代码,tls-宏.h https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/tls-macros.h;hb=HEAD, tlsdesc.c https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/tlsdesc.c;hb=HEAD等。很可能完整/简洁的答案将取决于以下版本:

  1. 你的 ARM CPU。
  2. 你的 Linux 内核。
  3. 你的 glibc.
  4. 您的编译器(和标志!)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARM 上 TLS 的代码序列 的相关文章

随机推荐