Merge "els-tls.md: stop talking about ELF TLS as future work." into main
diff --git a/docs/elf-tls.md b/docs/elf-tls.md
index 6b03841..450f362 100644
--- a/docs/elf-tls.md
+++ b/docs/elf-tls.md
@@ -1,5 +1,11 @@
# Android ELF TLS
+App developers probably just want to read the
+[quick ELS TLS status summary](../android-changes-for-ndk-developers.md#elf-tls-available-for-api-level-29)
+instead.
+
+This document covers the detailed design and implementation choices.
+
[TOC]
# Overview
@@ -210,7 +216,7 @@
* https://bugzilla.redhat.com/show_bug.cgi?id=1124987
* web search: [`"dlopen: cannot load any more object with static TLS"`][glibc-static-tls-error]
-Neither musl nor the Bionic TLS prototype currently allocate any surplus TLS memory.
+Neither bionic nor musl currently allocate any surplus TLS memory.
In general, supporting surplus TLS memory probably requires maintaining a thread list so that
`dlopen` can initialize the new static TLS memory in all existing threads. A thread list could be
@@ -484,19 +490,6 @@
[quietly ignored]: https://android.googlesource.com/platform/bionic/+/android-8.1.0_r48/linker/linker.cpp#2784
[added compatibility checks]: https://android-review.googlesource.com/c/platform/bionic/+/648760
-# Bionic Prototype Notes
-
-There is an [ELF TLS prototype] uploaded on Gerrit. It implements:
- * Static TLS Block allocation for static and dynamic executables
- * TLS for dynamically loaded and unloaded modules (`__tls_get_addr`)
- * TLSDESC for arm64 only
-
-Missing:
- * `dlsym` of a TLS variable
- * debugger support
-
-[ELF TLS prototype]: https://android-review.googlesource.com/q/topic:%22elf-tls-prototype%22+(status:open%20OR%20status:merged)
-
## Loader/libc Communication
The loader exposes a list of TLS modules ([`struct TlsModules`][TlsModules]) to `libc.so` using the
@@ -510,13 +503,14 @@
## TLS Allocator
-The prototype currently allocates a `pthread_internal_t` object and static TLS in a single mmap'ed
+bionic currently allocates a `pthread_internal_t` object and static TLS in a single mmap'ed
region, along with a thread's stack if it needs one allocated. It doesn't place TLS memory on a
preallocated stack (either the main thread's stack or one provided with `pthread_attr_setstack`).
The DTV and blocks for dlopen'ed modules are instead allocated using the Bionic loader's
-`LinkerMemoryAllocator`, adapted to avoid the STL and to provide `memalign`. The prototype tries to
-achieve async-signal safety by blocking signals and acquiring a lock.
+`LinkerMemoryAllocator`, adapted to avoid the STL and to provide `memalign`.
+The implementation tries to achieve async-signal safety by blocking signals and
+acquiring a lock.
There are three "entry points" to dynamically locate a TLS variable's address:
* libc.so: `__tls_get_addr`
@@ -524,10 +518,10 @@
* loader: dlsym
The loader's entry points need to call `__tls_get_addr`, which needs to allocate memory. Currently,
-the prototype uses a [special function pointer] to call libc.so's `__tls_get_addr` from the loader.
+the implementation uses a [special function pointer] to call libc.so's `__tls_get_addr` from the loader.
(This should probably be removed.)
-The prototype currently allows for arbitrarily-large TLS variable alignment. IIRC, different
+The implementation currently allows for arbitrarily-large TLS variable alignment. IIRC, different
implementations (glibc, musl, FreeBSD) vary in their level of respect for TLS alignment. It looks
like the Bionic loader ignores segments' alignment and aligns loaded libraries to 256 KiB. See
`ReserveAligned`.
@@ -536,7 +530,7 @@
## Async-Signal Safety
-The prototype's `__tls_get_addr` might be async-signal safe. Making it AS-safe is a good idea if
+The implementation's `__tls_get_addr` might be async-signal safe. Making it AS-safe is a good idea if
it's feasible. musl's function is AS-safe, but glibc's isn't (or wasn't). Google had a patch to make
glibc AS-safe back in 2012-2013. See:
* https://sourceware.org/glibc/wiki/TLSandSignals
@@ -545,7 +539,7 @@
## Out-of-Memory Handling (abort)
-The prototype lazily allocates TLS memory for dlopen'ed modules (see `__tls_get_addr`), and an
+The implementation lazily allocates TLS memory for dlopen'ed modules (see `__tls_get_addr`), and an
out-of-memory error on a TLS access aborts the process. musl, on the other hand, preallocates TLS
memory on `pthread_create` and `dlopen`, so either function can return out-of-memory. Both functions
probably need to acquire the same lock.
@@ -567,7 +561,7 @@
FWIW: emutls also aborts on out-of-memory.
-## ELF TLS Not Usable in libc
+## ELF TLS Not Usable in libc Itself
The dynamic loader currently can't use ELF TLS, so any part of libc linked into the loader (i.e.
most of it) also can't use ELF TLS. It might be possible to lift this restriction, perhaps with
@@ -644,7 +638,7 @@
It seems easy to fix the incompatibility for variant 2 (x86 and x86_64) by splitting out the Bionic
slots into a new data structure. Variant 1 is a harder problem.
-The TLS prototype currently uses a patched LLD that uses a variant 1 TLS layout with a 16-word TCB
+The TLS prototype used a patched LLD that uses a variant 1 TLS layout with a 16-word TCB
on all architectures.
Aside: gcc's arm64ilp32 target uses a 32-bit unsigned offset for a TLS IE access
@@ -816,8 +810,8 @@
### Workaround for Go: place pthread keys after the executable's TLS
-Most Android executables do not use any `thread_local` variables. In the current prototype, with the
-AOSP hikey960 build, only `/system/bin/netd` has a TLS segment, and it's only 32 bytes. As long as
+Most Android executables do not use any `thread_local` variables. In the prototype, with the
+AOSP hikey960 build, only `/system/bin/netd` had a TLS segment, and it was only 32 bytes. As long as
`/system/bin/app_process{32,64}` limits its use of TLS memory, then the pthread keys could be
allocated after `app_process`' TLS segment, and Go will still find them.
@@ -842,6 +836,12 @@
* It looks like glibc's ld.so re-relocates itself after loading a program, so a program's symbols
can interpose call in the loader: https://sourceware.org/ml/libc-alpha/2014-01/msg00501.html
+## TODO: Other
+
+Missing:
+ * `dlsym` of a TLS variable
+ * debugger support
+
# References
General (and x86/x86-64)