linux - ARM 上 TLS 的代码序列

标签 linux arm elf abi thread-local-storage

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等。完整/简洁的答案很可能取决于版本,

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

关于linux - ARM 上 TLS 的代码序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29818269/

相关文章:

linux - 是否可以为 Linux/ARM 构建和运行 Go 插件?

assembly - (ARM 汇编)将寄存器右移 1 将所有位设置为零

c++ - 用于预填充运行时使用的对象的 ELF INIT 部分代码

php - 为什么我们在 Windows 中需要 CURLOPT_SSL_VERIFYPEER

linux - 命名管道是否清除读取数据

c++ - 交叉编译Qt for ARM时出错

linux - 节头列表指向哪个字符串表?

arm - 如何区分elf文件中的thumb指令和a​​rm指令?

php - 在 PHP 中使用 shell_exec() 函数时没有任何反应

linux - 如何识别系统是否已启动?