Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
runtime: remove assumptions on Android Bionic's TLS layout #29674
What version of Go are you using (
What are the chances that x86 Bionic could implement TLS relocations as they are implemented on x86 GNU/Linux systems? Because then I think everything would just work.
Reserving a register on amd64 would break all existing assembly code, which means breaking a lot of crypto packages. I think that would be difficult. Though the ABI support in 1.12 might provide a stepping stone toward supporting that.
I don't fully understand your TLS IE example for amd64. It seems to assume that the offset from
In glibc, certain offsets from
changed the title
Android Go's g TLS allocation makes assumptions about Bionic's TLS layout
Jan 11, 2019
Implementing the relocations is straightforward. The difficulty is that Go always uses static TLS ("IE" accesses), even though an Android app's solib is loaded with dlopen. Using IE in an solib doesn't generally work, because libc needs to allocate a thread's static TLS memory before it starts running, and it can't move/extend that memory when dlopen is called later. It can work if the libc reserves enough surplus static TLS memory. glibc reserves space (
The surplus amount needs to be enough for all dlopen'ed solibs. Once it's exhausted, dlopen fails.
There are other problems with surplus static TLS involving (a) initialization and (b) the
On GNU/Linux, Go uses a TLS LE access in an executable, and each access is a single instruction, e.g.:
The offset is known at build-time and encoded into the instruction. Typically the static linker would encode the offset, but I think Go's compiler knows that the runtime.tlsg symbol is at offset -8 and can encode it earlier.
In a GNU/Linux shared object (
The dynamic loader computes the TPOFF value for the solib's TLS segment and writes it into the GOT.
My proposal is to use something resembling TLS IE, but instead of storing the TPOFF in the GOT at load-time, it's computed at run-time and stored in an ordinary STB_LOCAL symbol.
We could allocate a TLS slot that Go could use, but I think we're hesitant to give one to a particular language runtime if we can avoid it.
If we did allocate a slot today, Go would only be able to use it on new versions of Android. That's problematic for Android/x86 because it uses TLS LE in the app solib, e.g.:
The situation for Android/ARM is better. For ARM, Go is already computing a TP-relative offset at run-time.
referenced this issue
Jan 15, 2019
I think that I have now paged enough memory to say that this seems reasonable to me. Thanks.
Ok, I think Bionic can add an API like the one I've proposed, and then I can upload a patch for Go to use the API on arm/arm64. Fixing x86 is more involved, though -- maybe someone on the Go team could look at that?
I'll work on adding the Bionic API.