ARM上TLS的代码序列

mwh*_*son 5 linux arm elf abi thread-local-storage

ELF处理线程局部存储文件给出了各种模型装配顺序(本地的exec /初始EXEC /一般动态)的各种架构.但不是ARM - 我能在哪里看到ARM的代码序列吗?我正在编写一个编译器,并希望生成能够与平台链接器(程序和动态)一起正常运行的代码.

为清楚起见,我们假设一个ARMv7 CPU和一个非常新的内核和glibc(比如说3.13+/2.19+),但是如果这很容易解释,我也会对旧的hw/sw需要改变什么感兴趣.

art*_*ise 4

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

mrc p15, 0, rX, c13, c0, 2  @ get the user r/w register
Run Code Online (Sandbox Code Playgroud)

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

地址 0xffff0fe8 的目的似乎是您可以使用这 4 个字节,而不是直接使用上面的汇编器 ( rX== r0),因为对于某些地方的某些机器来说可能有所不同。


它取决于 CPU 类型。在entry-armv.S的向量页@0xffff0fe0中有一个helper ;如果硬件不支持,则它位于进程/线程结构中。文档位于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);
}
Run Code Online (Sandbox Code Playgroud)

您执行系统调用来设置 TLS 内容。 clone是一种设置线程上下文的方法。thread_info保存线程的所有寄存器;它可能与其他 .mm 共享一个mm(内存管理或进程内存视图)task_structtp_value即,每个创建的线程都有一个 thread_info 。

这里讨论ARM 实现。ELF/nptl/glibc 和 Linux 内核都涉及(和/或搜索术语以进行更多调查)。的系统调用get_tls()可能太昂贵,并且当前主线有一个向量页帮助程序(由所有线程/进程映射)。

一些 glibc 源代码、tls-macros.htlsdesc.c等。最有可能完整/简洁的答案将取决于以下版本:

  1. 你的 ARM CPU。
  2. 你的 Linux 内核。
  3. 你的glibc。
  4. 您的编译器(和标志!)。