casaroli opened a new pull request, #20812:
URL: https://github.com/apache/nuttx/pull/20812

   ## Summary
   
   A toolchain without native TLS (for example the Arm GNU toolchain for 
aarch64-none-elf, or arm-none-eabi 13 as in CI) compiles a `__thread` variable 
into calls to `__emutls_get_address()`. In a flat or protected CMake build, 
`nuttx_add_application()` links the extra libraries, libgcc too, into each 
loadable module (`MODULE m`, `DYNLIB y`). The linker puts `emutls.o` of libgcc 
into the module. That copy is built with the single thread model: all threads 
of the module share one instance of each `__thread` variable. The loader never 
binds the module to the per-thread version of libc.
   
   This PR links such a module with copies of the extra libraries in which 
`__emutls_get_address()` and `__emutls_register_common()` are local symbols 
(`objcopy -L`). The module keeps them undefined, and the loader binds them to 
libc through the system symbol table. The module still takes all the other 
helpers from libgcc. The new function `nuttx_add_module_extra_libraries()` 
makes the copies at build time in `module_libs/`, only when the build has a 
loadable module.
   
   depends-on: apache/nuttx/pull/20723 (it exports the per-thread 
`__emutls_get_address()` of libc in libc.csv). The Make build gets the same 
change in apache/nuttx-apps#3882 (`Application.mk`, `Library.mk`).
   
   ## Impact
   
   - CMake loadable modules of a flat or protected build that use `__thread`: 
each thread now has its own copy. Without the libc export, the module does not 
load (`Exported symbol "__emutls_get_address" not found`) instead of sharing 
one copy.
   - Modules without `__thread` variables: same link, with the copies of the 
libraries.
   - Kernel build programs: no change (they link libc, which comes before 
libgcc).
   
   ## Testing
   
   `qemu-armv8a:nsh` (flat, CMake, Arm GNU 14.2 aarch64-none-elf, QEMU HVF) 
with `CONFIG_ELF`, `CONFIG_EXECFUNCS_SYSTEM_SYMTAB`, `CONFIG_TLS_NELEM=4`, 
#20723 and #20807 (`get_environ_ptr` in libc.csv). The configure output of 
`qemu-armv8a:knsh` (kernel build) still links the programs with the libgcc of 
the toolchain, after libc. The test programs are built with `MODULE m` and 
loaded from a 9p share of the build directory.
   
   | Module | master | this PR |
   |---|---|---|
   | tlsgroup (2 threads) | FAIL (one address for all threads) | PASS |
   | tls4 (4 threads) | FAIL | PASS |
   | tlsmany (12 variables) | FAIL | PASS |
   | uctls (ucontext) | PASS | PASS |
   | tlscxx (C++ `thread_local`) | FAIL | PASS |
   
   `nm` of a module: master has `T __emutls_get_address` (from libgcc); this PR 
has `U __emutls_get_address`. The module link names `module_libs/libgcc.a` and 
`module_libs/libm.a`.
   
   The uctls test needs `getcontext()`, `makecontext()` and `swapcontext()` in 
libc.csv; the test tree added them locally.
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to