Ulrich Drepper关于线程本地存储的论文概述了几种不同 cpu 架构的 TLS ABI,但我发现它不足以作为实现 TLS 的基础,原因有两个:
- 它省略了一些重要的拱门,如 ARM、MIPS 等(同时包括一堆完全不相关的拱门,如安腾)
- 更重要的是,它将很多实现细节与 ABI 混合在一起,因此很难区分互操作性需要哪些属性,哪些只是他实现的方面。
例如,i386 的唯一实际 ABI 要求是:
%gs:0
指向一个指向自身的指针。- 主可执行文件的 TLS 段(如果有)必须位于距此地址的固定(通过链接器,为负)偏移处。
- 初始加载的库的所有其他 TLS 段必须有一个运行时常量(即每个线程相同,但在不同的程序运行中不一定相同)相对于该地址的偏移量(并且动态链接器必须能够用这些偏移量)。
___tls_get_addr
并且__tls_get_addr
函数必须以正确的语义存在,以查找任意 TLS 段。
特别是,DTV 的存在或布局不是ABI 的一部分,除主程序之外的 TLS 段的排序/布局也不是。
似乎任何使用“TLS 变体 II”的拱门都大致具有上述 ABI 要求。但是我根本不太了解“TLS 变体 I”的要求,而且从阅读资料(在 uClibc 和 glibc 中)看来,甚至可能有几个“变体 I”的变体。
有没有更好的文档我应该查看,或者熟悉 TLS 工作原理的人可以向我解释 ABI 要求吗?