macho 文件规范包括 S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 类型的部分。 在 MCSectionMachO.h 的 llvm 源中我找到了评论:
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - 包含指向函数的线程局部变量初始化指针的部分。
此外,在 libdylib 源代码中有明确的代码来处理这些:
http://www.opensource.apple.com/source/dyld/dyld-195.6/src/threadLocalVariables.c
具体来说,为 S_THREAD_LOCAL_VARIABLES 类型的部分分配 TLS 后,代码可以在分配的内存“之上”运行静态构造函数,以自定义方式对其进行初始化。
问题是我看不出如何导致编译器发出这样的部分。 显而易见的事情是使用函数初始化 thread_local 变量,例如
__thread int tl_int = foo();
然而,c++ 标准不允许这样做:
在 C++ 中,如果线程局部变量存在初始值设定项,则它必须是常量表达式,如 ANSI/ISO C++ 标准 5.19.2 中所定义。
参见 https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html。
有谁知道我如何使用高级代码生成这样的部分? 显然,通过组装、手动黑客或任何其他黑暗艺术来完成它并不是我在这里寻找的。
(请注意,我在上面使用 __thread 而不是 thread_local,因为 clang 似乎不支持 c++11 关键字 thread_local。深入了解这一点的加分 - 我还没有花太多精力来找出答案!)。
有了 clang 就可以使用
__attribute__((section("__DATA,__thread_init")))
这将创建具有
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
属性的部分。