Bug 9476 – Support native TLS on Mac OS X

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
Mac OS X
Creation time
2013-02-08T00:41:38Z
Last change time
2019-05-15T11:27:38Z
Assigned to
No Owner
Creator
Jacob Carlborg

Comments

Comment #0 by doob — 2013-02-08T00:41:38Z
Since Mac OS X Lion (10.7) and later native TLS is available. This is basically needed if we want to support dynamic libraries on Mac OS X. Otherwise we would need to do parts of what the dynamic linker is doing in druntime. Both DMD and druntime need to be changed for this. We need to be a bit careful when implementing this since this change will make DMD require Mac OS X 10.7 instead of currently 10.6. There's also always the option of doing what the dynamic linker is doing for TLS in druntime to keep the support for Mac OS X 10.6. I can add a bit more implementation details later.
Comment #1 by code — 2013-03-07T03:43:50Z
Can you provide any links or information? After searching around quite a lot I get the impression there is no native TLS support in OSX. The only thing I could find are related to __emutls_get_address calls created by certain clang/gcc version. At least the newest gcc (build 5658) doesn't support __thread out of the box.
Comment #2 by doob — 2013-03-07T04:34:32Z
Right, I forgot about this. This is some information for a couple of post I wrote in the newgroups: Original code: http://pastebin.com/UKb6etWD Disassembly with TLS: http://pastebin.com/nkdnE9w6 Disassembly without TLS: http://pastebin.com/vuvEBWWH Object dump with TLS: http://pastebin.com/PqpPw56a Object dump without TLS: http://pastebin.com/ki6atzEm The source code for the dynamic linker on Mac OS X 10.7+ with the TLS handling: http://opensource.apple.com/source/dyld/dyld-210.2.3/src/threadLocalHelpers.s http://opensource.apple.com/source/dyld/dyld-210.2.3/src/threadLocalVariables.c A description of what's basically happening in the source code above: "I've done some investigation. Currently DMD inserts a call to the __tls_get_addr function when accessing a TLS variable. This is implemented in druntime. In Mac OS X 10.7 it works similar but instead of inserting a call to __tls_get_addr there's a struct looking like this (written in D) : struct TLVDescriptor { void* function (TLVDescriptor*) thunk; size_t key; size_t offset; } The dynamic linker will iterate all loaded images and extract the section containing the TLS data. I guess this section consists of a list of TLVDescriptor*. The dynamic linker will set the "thunk" to a function "tlv_get_addrs", implemented in assembly in the dynamic linker. It will set the key to a key created by "pthread_key_create". It will also map the image with this key. This key is same for all TLVDescriptor of a given image. Instead of calling "__tls_get_addr" I think that the compiler will need to call the thunk passing in the TLVDescriptor itself to the thunk. The "tlv_get_addrs" function will then extract the key and from that key it can get the image the address belongs to. Does that make any sens? Is that something the DMD could do, that is call the thunk instead of "__tls_get_addr".?"
Comment #3 by code — 2013-03-07T07:05:20Z
(In reply to comment #2) > Right, I forgot about this. This is some information for a couple of post I > wrote in the newgroups: > > Original code: http://pastebin.com/UKb6etWD > > Disassembly with TLS: http://pastebin.com/nkdnE9w6 > Disassembly without TLS: http://pastebin.com/vuvEBWWH > How did you compile the code? Did you have to use a certain compiler and version?
Comment #4 by doob — 2013-03-07T08:23:27Z
(In reply to comment #3) > How did you compile the code? Did you have to use a certain compiler and > version? $ clang --version Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) Target: x86_64-apple-darwin12.2.0 Thread model: posix Mac OS X 10.8.2 Xcode Version 4.6 (4H127) The exact version used by Xcode would is: $ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) Target: x86_64-apple-darwin12.2.0 Thread model: posix But they give the same code. This is compiled for 32bit, if you haven't already figured that out.
Comment #5 by doob — 2013-03-07T08:26:39Z
GCC shipped with the same version of Xcode cannot build the code: $ gcc --version i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. I guess Apple doesn't really care about GCC anymore.
Comment #6 by doob — 2013-03-07T08:33:49Z
This thread might be of interest as well. It's from the Clang mailing list: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-November/025571.html
Comment #7 by code — 2013-03-11T11:25:13Z
The needed functionality appeared in dyld-195.5 and ld64-123.2. http://www.opensource.apple.com/source/dyld/dyld-195.5/src/threadLocalHelpers.s http://www.opensource.apple.com/source/dyld/dyld-195.5/src/threadLocalVariables.c If older linkers ignore the new sections and flags we probably might create objects using the new TLV mechanism and do the dyld part in druntime for older versions but I don't have time for this right now. NB: http://forum.dlang.org/thread/[email protected]
Comment #8 by doob — 2013-03-17T08:22:54Z
(In reply to comment #7) > The needed functionality appeared in dyld-195.5 and ld64-123.2. > http://www.opensource.apple.com/source/dyld/dyld-195.5/src/threadLocalHelpers.s > http://www.opensource.apple.com/source/dyld/dyld-195.5/src/threadLocalVariables.c > If older linkers ignore the new sections and flags we probably might create > objects using the new TLV mechanism and do the dyld part in druntime for older > versions but I don't have time for this right now. I was thinking the same thing, although Walter doesn't seem particular happy about the idea. On the other hand, I don't think he wants to drop the support for 10.6 yet. I think it should be fairly easy to port threadLocalVariables.c to D and include it in druntime. Although to would probably not be allowed to to license issues. What are our options here?
Comment #9 by doob — 2013-03-19T12:17:30Z
I could probably try implementing the code for druntime. But I don't think I have enough knowledge about DMD and TLS to make the necessary changes to DMD.
Comment #10 by kevin.lamonte — 2014-11-03T02:04:25Z
Rather than remove it, could the existing non-native OSX TLS model be made available via compile command-line argument for all platforms? Something like "-non-native-tls"? I am writing a bare-metal kernel (https://github.com/klamonte/cycle) in D (2.066.1-rc2) and am working on TLS support. It is made more difficult by compiling on Linux DMD with the much more complex sections_linux.d DSO model. I have gotten ModuleInfo to work without too much hassle using a small bit of linker script: .minfo : { start_minfo = . ; KEEP (*(SORT_NONE(.minfo))) end_minfo = . ; } (This BTW continues to work with --gc-sections.) I'd really like to be able to do similar for TLS, basically do the method described in the Dr Dobbs article for OSX TLS support but on my Linux system. I'll also need TLS in order for exceptions to work later on.
Comment #11 by john.loughran.colvin — 2014-11-11T14:31:45Z
I think the time has come that 10.6 support could be dropped, no? It's no longer supported by Apple.
Comment #12 by doob — 2014-11-11T15:39:29Z
(In reply to John Colvin from comment #11) > I think the time has come that 10.6 support could be dropped, no? It's no > longer supported by Apple. Fine by me.
Comment #13 by john.loughran.colvin — 2014-11-14T10:21:37Z
Some related chatter from ghc: https://ghc.haskell.org/trac/ghc/ticket/7602
Comment #14 by doob — 2016-01-10T20:50:59Z
Comment #15 by doob — 2019-05-15T11:27:38Z