2015-04-23 36 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