riscv64 TLS support.
Signed-off-by: Mao Han <han_mao@linux.alibaba.com>
Signed-off-by: Xia Lifang <lifang_xia@linux.alibaba.com>
Signed-off-by: Chen Guoyin <chenguoyin.cgy@linux.alibaba.com>
Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
Signed-off-by: Lu Xufan <luxufan@iscas.ac.cn>
Test: treehugger
Change-Id: I14efb4a03a3dc2ec736d7e47a3f8859c886eb9d6
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index d5fb05a..79893e3 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -137,6 +137,15 @@
offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), max_align);
return offset_bionic_tcb_ - exe_size;
+#elif defined(__riscv)
+
+ // First reserve enough space for the TCB before the executable segment.
+ offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), 1);
+
+ // Then reserve the segment itself.
+ const size_t exe_size = round_up_with_overflow_check(exe_segment->size, exe_segment->alignment);
+ return reserve(exe_size, 1);
+
#else
#error "Unrecognized architecture"
#endif
@@ -312,7 +321,7 @@
}
}
- return static_cast<char*>(mod_ptr) + ti->offset;
+ return static_cast<char*>(mod_ptr) + ti->offset + TLS_DTV_OFFSET;
}
// Returns the address of a thread's TLS memory given a module ID and an offset
@@ -332,7 +341,7 @@
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)) {
- return static_cast<char*>(mod_ptr) + ti->offset;
+ return static_cast<char*>(mod_ptr) + ti->offset + TLS_DTV_OFFSET;
}
}