2015-04-23 95 views
5

ELF Handling For Thread-Local Storage文档为各种体系结构提供了各种模型(本地执行/初始执行/常规动态)的汇编序列。但不是ARM - 是否有任何地方可以看到ARM的这种代码序列?我正在编译一个编译器,并希望生成能够在平台链接器(包括程序和动态链接)下正常运行的代码。为了清楚起见,我们假设一个ARMv7 CPU和一个非常新的内核和glibc(比如3.13+/2.19+),但是如果容易解释的话,我也会对旧的hw/sw有什么变化感兴趣。ARM上用于TLS的代码序列

+1

我会做一些反汇编(http://goo.gl/TPiQCX),然后使用这些谷歌。 https://gcc.gnu.org/ml/gcc-patches/2005-03/msg02375.html http://sourcery.mentor.com/public/publications/RFC-TLSDESC-ARM.txt http:// lxr。 free-electrons.com/source/arch/arm/include/asm/tls.h – auselen

+0

可以说是http:// stackoverflow的副本。com/questions/12878698/what-are-real-elf-tls-abi-requirements-for-each-cpu-arch,但那个没有正确的答案。 – unixsmurf

+0

@unixsmurf我认为'R对他的问题的回答以及如何在ARM-Linux下获得'线程注册'回答这个问题? –

回答

2

我不完全明白你想要什么。但是,汇编序列(对ARMv6 +和一种能够内核)是,

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

这被称为TPIDRURW在一些ARM手册。您的TLS表格/结构必须由此值(可能是指针)派生。使用mcr速度更快,但如果您在ELF中没有设置HWCAP_TLS(可用于Linux支持的所有ARM CPU),则也可以调用助手(请参见下文)。

地址0xffff0fe8 的意图似乎是可以使用的,而不是直接使用上述汇编器(rX == r0)的4个字节的也许是一些机器不同的地方。


它取决于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共享一个毫米(内存管理或进程内存视图)。即,对于每个创建的线程,thread_info都有一个tp_value

Here is a dicussion的ARM实现。 ELF/nptl/glibc和Linux内核都涉及(和/或搜索术语来调查更多)。 get_tls()的系统调用可能太昂贵了,而且当前的主线有一个矢量页面助手(由所有线程/进程映射)。

一些glibc的源,tls-macros.htlsdesc.c等最有可能是全/简洁的答案将取决于版本,

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

您参考的PDF中的** TCB **是ARM-Linux下的'thread_info'结构。哦,当然还有'ld'(装载机)。 CP15 c13,c0在ARMv6 +上使用。有三个注册表。用户r/w,用户只读和特权(仅限内核);内核必须能够编写所有这些内核。 ARM Linux只使用两个(如tp_values);除此之外,如果你正在ARM上实现这些,其他**汇编器序列则可以达到你的想象。也就是说,你的问题对我来说不是很清楚;你想重新使用* glibc * loader还是自己编写所有的用户空间? –

+0

感谢您的回复。我认为这是mrc指令让我感到困惑。我总是忘记了ARM CPU版本的混乱。我将编辑问题,然后也许你可以编辑答案。 – mwhudson