Emulated TLS for Android

Joakim via digitalmars-d-ldc digitalmars-d-ldc at puremagic.com
Thu Jul 6 04:13:20 PDT 2017

So I've finally spent some time looking at this, ie what work 
google did to get a gcc-alike emulated TLS into llvm, since 
they've ditched the gcc compiler from their Native Development 
Kit (NDK):


It simply modifies llvm to call __emutls_get_address from libgcc 
(a library the NDK still supplies) anytime your code accesses a 
thread-local variable, but there's no hook in 
__emutls_get_address that I can use to register that data with 
the D GC:


I can compile and run much D code fine with llvm's emulated TLS- 
all of druntime's tests pass- but start having problems because 
it's not registered with the GC, a dozen or so Phobos modules' 
tests fail or segfault in somewhat random ways.

Three ways to fix this come to mind:

1. Intercept all calls to thread-local variables at runtime and 
make sure they're registered with the GC, ie by inserting some 
registering function after __emutls_get_address.  This would 
require deeper knowledge of ldc and llvm than I have, one of you 
would probably have to do it.  Also, we'd now be depending on 
libgcc for its emulated TLS, ie another dependency.

2. Intercept __emutls_get_address when linking and replace it 
with our own implementation, rather than depending on libgcc's 
version.  This can be done, I tried it with an empty function.  A 
drawback is that it appears that you don't know how large the 
emulated thread-local data section will be, which I think is why 
they keep extending it in the libgcc implementation linked above.

3. Modify my llvm patch that keeps TLS data where it is in other 
platforms, ie .tdata/.tbss, but removes the SHF_TLS/STT_TLS ELF 
flags, adds section delimiting symbols _tlsstart and _tlsend, and 
replaces the TLS relocation with a normal one (pretty much 
Walter's emulated TLS for OS X: 
https://gist.github.com/joakim-noah/1fb23fba1ba5b7e87e1a), so 
that it is enabled for Android behind a runtime flag and apply it 
to our llvm source before building it.

Initially it'd only have to be for releases, but if we get an 
Android CI going, it'd have to be applied for that too.  Because 
_tlsstart is applied for the module with main, that object has to 
be linked first.

I'm leaning towards 3., it's the easiest and I'm not too keen on 
how the libgcc version works.

Since 3. will require patching our llvm, let me know what you 
think we should do.

With this last change, ldc will have Android cross-compilation 
support from every platform that's part of the official release.  
Until we get some way to generate a cross-compiled stdlib from 
the compiler and accompanying source, I can put up a tarfile with 
the cross-compiled stdlib for Android, though they'll need the 
NDK for their platform for its native Android libraries and 

More information about the digitalmars-d-ldc mailing list