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 @@ -25,7 +25,10 @@ fn main() { 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 @@ -211,6 +212,7 @@ #if defined(__GNUC__) && (__GNUC__ >= 7) && defined(__aarch64__) /* special case aarch64 for older gcc versions (issue #851) */ \ && !defined(__APPLE__) /* on apple (M1) the wrong register is read (tpidr_el0 instead of tpidrro_el0) so fall back to TLS slot assembly ()*/ \ && (!defined(__clang_major__) || __clang_major__ >= 14) /* older clang versions emit bad code; fall back to using the TLS slot () */ + && (!defined(__ANDROID__) || __ANDROID_API__ >= 29) /* __builtin_thread_pointer will omit calls to __aeabi_read_tp on arm Android, and causes build failure when __ANDROID_API__ < 29 */ #define MI_USE_BUILTIN_THREAD_POINTER 1 #endif