每个cpu arch的真正ELF TLS ABI要求是什么?

[英]What are the real ELF TLS ABI requirements for each cpu arch?


Ulrich Drepper's paper on thread-local storage outlines the TLS ABI for several different cpu architectures, but I'm finding it insufficient as a basis for implementing TLS for two reasons:

Ulrich Drepper关于线程本地存储的论文概述了几种不同cpu架构的TLS ABI,但我发现它不足以作为实现TLS的基础,原因有两个:

  1. It omits a number of important archs like ARM, MIPS, etc. (while including a bunch of completely-irrelevant ones like Itanium)
  2. 它省略了许多重要的拱门,如ARM,MIPS等(虽然包括一堆与Itanium完全无关的)
  3. More importantly, it mixes a lot of implementation details with ABI, so that it's hard to tell which properties are required for interoperability, and which are just aspects of his implementation.
  4. 更重要的是,它将大量实现细节与ABI混合在一起,因此很难说出互操作性需要哪些属性,哪些只是其实现的一部分。

As an example, the only actual ABI requirements for i386 are:

例如,i386唯一的实际ABI要求是:

  • %gs:0 points to a pointer to itself.
  • %gs:0指向指向自身的指针。
  • The main executable's TLS segment, if any, must be located at a fixed (by the linker, negative) offset from this address.
  • 主可执行文件的TLS段(如果有)必须位于此地址的固定(通过链接器,负)偏移量。
  • All other TLS segments for initially-loaded libraries must have a runtime-constant (i.e. same for each thread, but not necessarily the same across different program runs) offsets relative to this address (and the dynamic linker must be able to fill in relocations with these offsets).
  • 初始加载的库的所有其他TLS段必须具有相对于此地址的运行时常量(即,对于每个线程相同,但在不同的程序运行中不一定相同)(并且动态链接器必须能够填充重定位)这些补偿)。
  • ___tls_get_addr and __tls_get_addr functions must exist with the correct semantics for looking up arbitrary TLS segments.
  • ___tls_get_addr和__tls_get_addr函数必须以正确的语义存在,以便查找任意TLS段。

In particular, the existence or layout of a DTV is not part of the ABI, nor is the ordering/layout of TLS segments other than the main program's.

特别是,DTV的存在或布局不是ABI的一部分,也不是主程序之外的TLS段的排序/布局。

It seems that any arch using "TLS variant II" has roughly the above ABI requirements. But I don't understand the requirements of "TLS variant I" very well at all, and it seems from reading sources (in uClibc and glibc) that there may even be several variants of "variant I".

似乎任何使用“TLS变体II”的拱门都具有大致上述ABI要求。但我完全不了解“TLS变体I”的要求,而且从阅读资料(在uClibc和glibc中)看来,甚至可能存在“变体I”的几种变体。

Are there any better documents I should be looking at, or can somebody familiar with the workings of TLS explain the ABI requirements to me?

有没有更好的文件我应该关注,或者熟悉TLS工作的人能否向我解释ABI要求?

1 个解决方案

#1


3  

The best I can gather so far is:

到目前为止我能收集到的最好的是:

For either TLS variant, __tls_get_addr or other arch-specific functions must exist and have the correct semantics for looking up any TLS object, and the relative offset between any two TLS segments must be a runtime constant (same offset for each thread).

对于任一TLS变体,__ tls_get_addr或其他特定于arch的函数必须存在并且具有用于查找任何TLS对象的正确语义,并且任何两个TLS段之间的相对偏移必须是运行时常量(每个线程的相同偏移量)。

For TLS variant II (i386, etc.), the "thread pointer register" (which may not actually be a register, but perhaps some mechanism like %gs:0 or even a trap into kernelspace; for simplicity though let's just call it a register) points just past the end of the TLS segment for the main executable, where "just past the end" includes rounding up to the next multiple of the TLS segment's alignment.

对于TLS变体II(i386等),“线程指针寄存器”(实际上可能不是寄存器,但可能是某些机制,如%gs:0或甚至陷入内核空间;为简单起见,我们只需将其称为register)指向主要可执行文件的TLS段的末尾,其中“刚刚结束”包括向上舍入到TLS段的下一个多个对齐。

For TLS variant I, the "thread pointer register" points to some fixed offset from the beginning of the TLS segment for the main executable. This offset varies by arch. (It has been chosen on some ugly RISC archs to maximize the amount of TLS accessible via signed 16-bit offsets, which strikes me as extremely useless since the compiler has no way of knowing whether the relocated offset will fit in 16 bits and thus must always generate the slower, larger 32-bit-offset code using load-upper/add instructions).

对于TLS变体I,“线程指针寄存器”指向主要可执行文件的TLS段开头的某个固定偏移量。这种偏移因拱而异。 (已经在一些丑陋的RISC拱门上选择了最大化通过带符号的16位偏移可访问的TLS数量,这让我觉得非常无用,因为编译器无法知道重定位的偏移量是否适合16位,因此必须总是使用load-upper / add指令生成更慢,更大的32位偏移代码。

As far as I can tell, nothing about TCBs, DTVs, etc. is part of the ABI, in the sense that applications are not permitted to access these structures, nor is the location of any TLS segment other than the main executable's part of the ABI. In both variants I and II, it makes sense to store implementation-internal information for the thread at a fixed offset from the "thread pointer register", in whichever way safely avoids overlapping the TLS segment.

据我所知,TCB,DTV等没有任何内容是ABI的一部分,因为不允许应用程序访问这些结构,也不是任何TLS段的位置,而不是主要可执行文件的一部分。 ABI。在变体I和II中,将线程的实现内部信息存储在与“线程指针寄存器”固定的偏移处是有意义的,以任何方式安全地避免重叠TLS段。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2012/10/14/2fb1e5fefe8edfd7378b504a1e16be57.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号