TLS-related functions (`__aeabi_read_tp`, `__tls_get_addr`) are not introduced to bionic libc until Android 10. `__builtin_thread_pointer` will omit calls to `__aeabi_read_tp` on arm, and causes build failure when `__ANDROID_API__` < 29. TLS slot 1 has been used to storage thread id since Android 1.6 [1], and hasn't changed until Android 14 [2,3]. If `__builtin_thread_pointer` is not available, the default code path uses the method mentioned above to obtain a unique thread id, and there doesn't seem to be anything wrong with this. If necessary in the future, other methods can be made up for it, such as calling `pthread_self`. Besides, force using Emulated TLS for better compatibility. [1]: https://android.googlesource.com/platform/bionic/+/refs/tags/android-1.6_r1/libc/private/bionic_tls.h#57 [2]: https://android.googlesource.com/platform/bionic/+/refs/heads/android14-dev/libc/platform/bionic/tls_defines.h#86 [3]: https://android.googlesource.com/platform/bionic/+/refs/heads/android14-dev/libc/platform/bionic/tls_defines.h#106 The error message is as follows. ``` = note: ld.lld: error: undefined symbol: __aeabi_read_tp >>> referenced by static.c >>> 98cfcaec7182b1d8-static.o:(mi_free) in archive /tmp/rustcp5Rvgx/liblibmimalloc_sys-7086a69efa004ab8.rlib >>> referenced by static.c >>> 98cfcaec7182b1d8-static.o:(_mi_arena_segment_clear_abandoned) in archive /tmp/rustcp5Rvgx/liblibmimalloc_sys-7086a69efa004ab8.rlib >>> referenced by static.c >>> 98cfcaec7182b1d8-static.o:(_mi_arena_segment_clear_abandoned) in archive /tmp/rustcp5Rvgx/liblibmimalloc_sys-7086a69efa004ab8.rlib >>> referenced 9 more times clang-17: error: linker command failed with exit code 1 (use -v to see invocation) ``` --- a/build.rs +++ b/build.rs @@ -24,7 +28,10 @@ let dynamic_tls = env::var("CARGO_FEATURE_LOCAL_DYNAMIC_TLS").is_ok(); - if target_family == "unix" && target_os != "haiku" { + if target_family == "unix" && target_os == "android" { + build.flag_if_supported("-femulated-tls"); + } + else if target_family == "unix" && target_os != "haiku" { if dynamic_tls { build.flag_if_supported("-ftls-model=local-dynamic"); } else { --- a/c_src/mimalloc/include/mimalloc/prim.h +++ b/c_src/mimalloc/include/mimalloc/prim.h @@ -205,7 +205,7 @@ // Do we have __builtin_thread_pointer? (do not make this a compound test as it fails on older gcc's, see issue #851) #if defined(__has_builtin) -#if __has_builtin(__builtin_thread_pointer) +#if __has_builtin(__builtin_thread_pointer) && (!defined(__ANDROID__) || __ANDROID_API__ >= 29) #define MI_HAS_BUILTIN_THREAD_POINTER 1 #endif #elif defined(__GNUC__) && (__GNUC__ >= 7) && defined(__aarch64__) // special case aarch64 for older gcc versions (issue #851)