1
0
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:
Keith Packard 2020-07-01 23:29:49 -07:00
parent a0d3436486
commit 531050ada2
5 changed files with 94 additions and 0 deletions

View File

@ -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

View File

@ -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(

View File

@ -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 */

View File

@ -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 :

View File

@ -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);