thread_local storage on 10.6.8 with clang-7.0

Ken Cunningham ken.cunningham.webuse at gmail.com
Fri Oct 5 17:50:32 UTC 2018


With a couple of very minor modifications, recent versions of clang will support thread_local storage including support for complex destructors on 10.6.8 using the same emutls.c system that gcc uses to support it. I'll attach the (amazingly simple) patches below. It picks up the emutls.c support from libgcc and libstdc++:

$ nm  /opt/local/lib/libgcc/libstdc++.6.dylib | grep cxa_thread
0000000000001e16 T ___cxa_thread_atexit

$ nm /opt/local/lib/libgcc/libgcc_s.1.dylib | grep emu
000000000000bd56 T ___emutls_get_address
000000000000bec7 T ___emutls_register_common


This works when we use the MacPorts alternate c++11 support Marcus came up with, using

-stdlib=macports-libstdc++

and it seems to me to pass all the tests of how thread_local should work that I can throw at it. So this seems very usable to me at present.




However, when using libc++ (my preferred setup) I'm still having a couple of issues getting cxa_thread_atexit and emutls_get_address to build into libc++abi and show up at runtime.

Using RJVB's libcxx Port, I have built libc++abi more in the LINUX way, with cxa_thread_atexit.cpp included (that was fairly easy), but it doesn't find the symbols in 

/opt/local/libexec/llvm-7.0/lib/clang/7.0.0/lib/darwin/libclang_rt.osx.a

that it needs to find and dies at runtime. I think it's possibly a visibility thing.

If there is anyone out there with any skills and interest in working on this please speak up and I'll bring you fully up to speed offline regarding my libc++/libc++abi build efforts

Best,

Ken


Patches for llvm/clang-7.0 to enable thread_local support using -stdlib=macports-libstdc++:

==========================
--- a/include/llvm/ADT/Triple.h.orig	2018-10-02 17:38:10.000000000 -0700
+++ b/include/llvm/ADT/Triple.h	2018-10-02 17:38:58.000000000 -0700
@@ -682,7 +682,7 @@
 
   /// Tests whether the target uses emulated TLS as default.
   bool hasDefaultEmulatedTLS() const {
-    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
+    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment() || isMacOSXVersionLT(10, 7);
   }
 
   /// @}
==========================
--- a/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp.orig	2018-10-02 18:31:17.000000000 -0700
+++ b/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp	2018-10-02 18:32:35.000000000 -0700
@@ -2255,7 +2255,7 @@
   const char *Name = "__cxa_atexit";
   if (TLS) {
     const llvm::Triple &T = CGF.getTarget().getTriple();
-    Name = T.isOSDarwin() ?  "_tlv_atexit" : "__cxa_thread_atexit";
+    Name = (T.isOSDarwin() && !T.isMacOSXVersionLT(10, 7)) ?  "_tlv_atexit" : "__cxa_thread_atexit";
   }
 
   // We're assuming that the destructor function is something we can
--- a/tools/clang/lib/Basic/Targets/OSTargets.h.orig	2018-10-02 17:14:10.000000000 -0700
+++ b/tools/clang/lib/Basic/Targets/OSTargets.h	2018-10-02 17:14:41.000000000 -0700
@@ -93,7 +93,7 @@
     this->TLSSupported = false;
 
     if (Triple.isMacOSX())
-      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
+      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 4);
     else if (Triple.isiOS()) {
       // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
       // 32-bit simulator from 10 onwards.
==========================



More information about the macports-users mailing list