diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp index b3f1680918a91009068d8479f47ca2ae53da3b1b..cce36c9f97cbeac5ab4d49a28957aa4dcc811206 100644 --- a/libc/bionic/bionic_elf_tls.cpp +++ b/libc/bionic/bionic_elf_tls.cpp @@ -138,12 +138,11 @@ size_t StaticTlsLayout::reserve_exe_segment_and_tcb(const TlsSegment* exe_segmen return offset_bionic_tcb_ - exe_size; #elif __riscv_xlen == 64 - + // FIXME: Align TCB block and EXE's segment more accurate. For current implementation, + // alignment requirement is not considered carefully. + offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), 1); const size_t exe_size = round_up_with_overflow_check(exe_segment->size, exe_segment->alignment); - reserve(exe_size, 1); - const size_t max_align = MAX(alignof(bionic_tcb), exe_segment->alignment); - offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), max_align); - return offset_bionic_tcb_ - exe_size; + return reserve(exe_size, 1); #else #error "Unrecognized architecture" @@ -320,7 +319,11 @@ __attribute__((noinline)) static void* tls_get_addr_slow_path(const TlsIndex* ti } } +#ifdef __riscv + return static_cast(mod_ptr) + ti->offset + TLS_DTV_OFFSET; +#else return static_cast(mod_ptr) + ti->offset; +#endif } // Returns the address of a thread's TLS memory given a module ID and an offset @@ -340,7 +343,11 @@ extern "C" void* TLS_GET_ADDR(const TlsIndex* ti) TLS_GET_ADDR_CCONV { if (__predict_true(generation == dtv->generation)) { void* mod_ptr = dtv->modules[__tls_module_id_to_idx(ti->module_id)]; if (__predict_true(mod_ptr != nullptr)) { +#ifdef __riscv + return static_cast(mod_ptr) + ti->offset + TLS_DTV_OFFSET; +#else return static_cast(mod_ptr) + ti->offset; +#endif } } diff --git a/libc/platform/bionic/tls_defines.h b/libc/platform/bionic/tls_defines.h index 225722d72dcce0c3c1dbdf11e781470690deb22f..225e32301efd7411c22e8a9a7f251338c9824da6 100644 --- a/libc/platform/bionic/tls_defines.h +++ b/libc/platform/bionic/tls_defines.h @@ -96,19 +96,19 @@ #elif __riscv_xlen == 64 -#define MIN_TLS_SLOT 0 - -#define TLS_SLOT_SELF 0 -#define TLS_SLOT_THREAD_ID 1 -#define TLS_SLOT_APP 2 // was historically used for errno -#define TLS_SLOT_OPENGL 3 -#define TLS_SLOT_OPENGL_API 4 -#define TLS_SLOT_STACK_GUARD 5 -#define TLS_SLOT_SANITIZER 6 // was historically used for dlerror -#define TLS_SLOT_ART_THREAD_SELF 7 -#define TLS_SLOT_DTV 8 -#define TLS_SLOT_BIONIC_TLS 9 -#define MAX_TLS_SLOT 9 // update this value when reserving a slot +#define MIN_TLS_SLOT -10 + +#define TLS_SLOT_SELF -10 +#define TLS_SLOT_THREAD_ID -9 +#define TLS_SLOT_APP -8 // was historically used for errno +#define TLS_SLOT_OPENGL -7 +#define TLS_SLOT_OPENGL_API -6 +#define TLS_SLOT_STACK_GUARD -5 +#define TLS_SLOT_SANITIZER -4 // was historically used for dlerror +#define TLS_SLOT_ART_THREAD_SELF -3 +#define TLS_SLOT_DTV -2 +#define TLS_SLOT_BIONIC_TLS -1 +#define MAX_TLS_SLOT -1 // update this value when reserving a slot #elif defined(__i386__) || defined(__x86_64__) diff --git a/libc/private/bionic_elf_tls.h b/libc/private/bionic_elf_tls.h index e0ec7b51dc7d8a7bf590aeedaa262f8208f33112..372ac610b06d897874d160caaf08d0ee8e6115ac 100644 --- a/libc/private/bionic_elf_tls.h +++ b/libc/private/bionic_elf_tls.h @@ -201,3 +201,7 @@ extern "C" void* TLS_GET_ADDR(const TlsIndex* ti) TLS_GET_ADDR_CCONV; struct bionic_tcb; void __free_dynamic_tls(bionic_tcb* tcb); void __notify_thread_exit_callbacks(); + +#if defined(__riscv) +#define TLS_DTV_OFFSET 0x800 +#endif \ No newline at end of file