ARM上TLS的代码序列

时间:2015-04-23 08:49:16

标签: linux arm elf abi thread-local-storage

ELF Handling For Thread-Local Storage文档为各种体系结构提供了各种模型(本地exec /初始exec /一般动态)的汇编序列。但不是ARM - 我能在哪里看到ARM的代码序列吗?我正在编写一个编译器,希望生成能够与平台链接器(程序和动态)一起正常运行的代码。

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

1 个答案:

答案 0 :(得分:2)

我不完全明白你想要什么。但是,汇编程序序列(对于ARMv6 +和一个有能力的内核)是

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

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

地址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 (内存管理或进程内存视图)。也就是说,thread_info对每个创建的线程都有一个tp_value

ARM实现的

Here is a dicussion。 ELF / nptl / glibc和Linux内核都涉及(和/或搜索术语以进行更多调查)。 get_tls()的系统调用可能过于昂贵,当前主线有一个矢量页面帮助器(由所有线程/进程映射)。

一些glibc来源,tls-macros.htlsdesc.c等。很可能完整/简明的答案取决于版本,

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