This is an automated email from the ASF dual-hosted git repository.

linguini1 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 84dc58088e5 arch/risc-v: Fix TLS size and initialization to use byte 
offsets.
84dc58088e5 is described below

commit 84dc58088e55a56bac0b651ec054daf155de4a39
Author: raiden00pl <[email protected]>
AuthorDate: Mon Oct 12 17:41:04 2026 +0200

    arch/risc-v: Fix TLS size and initialization to use byte offsets.
    
    The linker symbols _stdata/_etdata/_stbss/_etbss are uint8_t arrays
    since commit 70290b6e38 ("arch: Change the linker generated symbols from
    uint32_t to uint8_t *"), but riscv_tls.c still multiplied their
    differences by sizeof(uint32_t).  up_tls_size() reserved four times the
    TLS block size and up_tls_initialize() copied four times the size of
    .tdata, so the bytes that follow .tdata in the image (.data) overwrote
    the .tbss variables of every new thread.
    
    ARM had the same problem and was fixed by commit fac76746eae ("arch/arm:
    Fix TLS initialization to account for padding between sections").
    Apply the same change here: use byte differences, and zero .tbss after
    the alignment padding between .tdata and .tbss.
    
    Found with CPython on rv-virt (CONFIG_SCHED_THREAD_LOCAL=y, toolchain
    built with --enable-tls): _Py_tss_tstate in .tbss was not NULL in new
    threads, "Fatal Python error: _PyThreadState_Attach: non-NULL old thread
    state".  Not seen in CI: the xPack riscv-none-elf toolchain is built with
    --disable-tls, so __thread uses emulated TLS and .tdata/.tbss are empty.
    
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: raiden00pl <[email protected]>
---
 arch/risc-v/src/common/riscv_tls.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/risc-v/src/common/riscv_tls.c 
b/arch/risc-v/src/common/riscv_tls.c
index e15b3133418..46fa2eeaa52 100644
--- a/arch/risc-v/src/common/riscv_tls.c
+++ b/arch/risc-v/src/common/riscv_tls.c
@@ -47,8 +47,7 @@
 
 int up_tls_size(void)
 {
-  return sizeof(struct tls_info_s) +
-         sizeof(uint32_t) * (_END_TBSS - _START_TDATA);
+  return sizeof(struct tls_info_s) + (_END_TBSS - _START_TDATA);
 }
 
 /****************************************************************************
@@ -65,10 +64,9 @@ int up_tls_size(void)
 void up_tls_initialize(struct tls_info_s *info)
 {
   uint8_t *tls_data = (uint8_t *)(info + 1);
-
-  uint32_t tdata_len = sizeof(uint32_t) * (_END_TDATA - _START_TDATA);
-  uint32_t tbss_len = sizeof(uint32_t) * (_END_TBSS - _START_TBSS);
+  uint32_t tdata_len = _END_TDATA - _START_TDATA;
+  uint32_t tbss_len = _END_TBSS - _START_TBSS;
 
   memcpy(tls_data, _START_TDATA, tdata_len);
-  memset(tls_data + tdata_len, 0, tbss_len);
+  memset(tls_data + tdata_len + (_START_TBSS - _END_TDATA), 0, tbss_len);
 }

Reply via email to