ARM上TLS的代码序列

线程本地存储文档的ELF处理为各种体系结构提供了各种模型(本地执行/初始执行/通用dynamic)的汇编序列。 但不是ARM – 有没有我能看到这样的ARM代码序列的地方? 我正在编译器,并希望生成代码将与平台链接器(包括程序和dynamic)正常运行。

为了清楚起见,我们假设一个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 (可以在Linux支持的所有ARM CPU上使用),也可以调用助手(见下文)。

地址0xffff0fe8的意图似乎是,你可以使用这些4字节,而不是直接用( rX == r0 )来使用上面的汇编程序,因为某些机器可能不同。


这取决于CPU类型。 entry-armv.S中的矢量页面@ 0xffff0fe0中有一个帮助器 ; 如果硬件不支持它,它在进程/线程结构中。 文档位于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实现的一个讨论 。 ELF / nptl / glibc和Linux内核都涉及(和/或搜索术语来调查更多)。 get_tls()的系统调用可能太昂贵了,当前的主线有一个向量页面助手(由所有线程/进程映射)。

一些glibc源码, tls-macros.h , tlsdesc.c等。最有可能的一个完整/简洁的答案将取决于版本,

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