mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
picolibc: Enable TLS support [v4]
Allocate and initialize a thread-local block for each thread at the top of the stack. Set the tls base when switching to a new thread. Add tdata/tbss linker instructions to cortex_m and risc-v scripts. Signed-off-by: Keith Packard <keithp@keithp.com> --- v2: Squash fixes v3: Replace tabs with spaces v4: Add tbss to fe310 linker script
This commit is contained in:
parent
a0d3436486
commit
531050ada2
@ -176,6 +176,10 @@ struct _thread {
|
||||
const char *name; /**< thread's name */
|
||||
int stack_size; /**< thread's stack size */
|
||||
#endif
|
||||
/* enable TLS only when Picolibc is compiled with TLS enabled */
|
||||
#ifdef PICOLIBC_TLS
|
||||
void *tls; /**< thread local storage ptr */
|
||||
#endif
|
||||
#ifdef HAVE_THREAD_ARCH_T
|
||||
thread_arch_t arch; /**< architecture dependent part */
|
||||
#endif
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef PICOLIBC_TLS
|
||||
#include <picotls.h>
|
||||
#endif
|
||||
|
||||
/* Needed by OpenOCD to read sched_threads */
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define FORCE_USED_SECTION __attribute__((used)) __attribute__((section( \
|
||||
@ -148,6 +152,9 @@ int __attribute__((used)) sched_run(void)
|
||||
next_thread->status = STATUS_RUNNING;
|
||||
sched_active_pid = next_thread->pid;
|
||||
sched_active_thread = next_thread;
|
||||
#ifdef PICOLIBC_TLS
|
||||
_set_tls(next_thread->tls);
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_MPU_STACK_GUARD
|
||||
mpu_configure(
|
||||
|
@ -20,6 +20,9 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#ifdef PICOLIBC_TLS
|
||||
#include <picotls.h>
|
||||
#endif
|
||||
|
||||
#include "assert.h"
|
||||
#include "thread.h"
|
||||
@ -215,6 +218,13 @@ kernel_pid_t thread_create(char *stack, int stacksize, uint8_t priority,
|
||||
/* allocate our thread control block at the top of our stackspace */
|
||||
thread_t *thread = (thread_t *)(stack + stacksize);
|
||||
|
||||
#ifdef PICOLIBC_TLS
|
||||
stacksize -= _tls_size();
|
||||
|
||||
thread->tls = stack + stacksize;
|
||||
_init_tls(thread->tls);
|
||||
#endif
|
||||
|
||||
#if defined(DEVELHELP) || defined(SCHED_TEST_STACK)
|
||||
if (flags & THREAD_CREATE_STACKTEST) {
|
||||
/* assign each int of the stack the value of it's address */
|
||||
|
@ -96,6 +96,42 @@ SECTIONS
|
||||
_efixed = .; /* End of text section */
|
||||
} > rom
|
||||
|
||||
/*
|
||||
* TLS relocations are offsets relative to the address
|
||||
* of the first TLS symbol. That means we just need to
|
||||
* allocate them all together so that the TLS region
|
||||
* is compact when allocated for each thread.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TLS initialization data is loaded into ROM so that
|
||||
* each thread can get its values initialized from there
|
||||
* at startup
|
||||
*/
|
||||
.tdata :
|
||||
{
|
||||
__tdata_start = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} > rom
|
||||
__tdata_source = LOADADDR(.tdata);
|
||||
__tdata_size = SIZEOF(.tdata);
|
||||
|
||||
/*
|
||||
* TLS zeroed data is relocated as if it immediately followed
|
||||
* the tdata values. However, the linker 'magically' erases the
|
||||
* memory allocation so that no ROM is consumed by this
|
||||
* section
|
||||
*/
|
||||
.tbss :
|
||||
{
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon)
|
||||
__tbss_end = .;
|
||||
} > rom
|
||||
__tls_size = __tbss_end - __tdata_start;
|
||||
__tbss_size = __tls_size - __tdata_size;
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
PROVIDE_HIDDEN (__exidx_start = .);
|
||||
.ARM.exidx :
|
||||
|
@ -27,6 +27,7 @@ PHDRS
|
||||
flash PT_LOAD;
|
||||
ram_init PT_LOAD;
|
||||
ram PT_NULL;
|
||||
tls PT_TLS;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
@ -118,6 +119,42 @@ SECTIONS
|
||||
KEEP (*(.dtors))
|
||||
} >flash AT>flash :flash
|
||||
|
||||
/*
|
||||
* TLS relocations are offsets relative to the address
|
||||
* of the first TLS symbol. That means we just need to
|
||||
* allocate them all together so that the TLS region
|
||||
* is compact when allocated for each thread.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TLS initialization data is loaded into ROM so that
|
||||
* each thread can get its values initialized from there
|
||||
* at startup
|
||||
*/
|
||||
.tdata :
|
||||
{
|
||||
__tdata_start = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} >flash AT>flash :tls
|
||||
__tdata_source = LOADADDR(.tdata);
|
||||
__tdata_size = SIZEOF(.tdata);
|
||||
|
||||
/*
|
||||
* TLS zeroed data is relocated as if it immediately followed
|
||||
* the tdata values. However, the linker 'magically' erases the
|
||||
* memory allocation so that no ROM is consumed by this
|
||||
* section
|
||||
*/
|
||||
.tbss :
|
||||
{
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon)
|
||||
__tbss_end = .;
|
||||
} >flash : tls
|
||||
__tls_size = __tbss_end - __tdata_start;
|
||||
__tbss_size = __tls_size - __tdata_size;
|
||||
|
||||
.lalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
|
Loading…
Reference in New Issue
Block a user