[PING]: [PATCH] newlib: import TLS initialization and helpers from picolibc

Torbjorn SVENSSON torbjorn.svensson@foss.st.com
Fri Aug 28 13:09:46 GMT 2026


Gentle ping! :)

Kind regards,
Torbjörn

On 2026-08-20 12:00, Torbjörn SVENSSON wrote:
> Hi,
> 
> With the decision from Arm to build a GCC toolchain without --disable-tls,
> newlib needs to have support in the start code to initialize the TLS block
> and implement __aeabi_read_tp to allow GCC to know what thread is current.
> 
> The change in the build rules were done in:
> https://gitlab.arm.com/tooling/gnu-devtools-for-arm/-/commit/f6a8633309c850d62817859986a165c94f11babf
> 
> Below patch imports the implementation from picolibc and leaves the header
> filenames as-is, thus, the main header file to include in an application
> is picotls.h
> 
> Note: This implementation primarily targets TLS mode local-exec. Other
> modes might require additional functions to be added.
> Also, I've only ported the parts that I've seen as required for
> arm-none-eabi, other targets might benefit from TLS support, but I do not
> have access to other hardware to validate the implementation on.
> 
> For TLS to be properly supported on arm-none-eabi, the following fix is
> also required in ld:
> https://sourceware.org/pipermail/binutils/2026-August/150870.html
> 
> 
> Ok for master?
> 
> Kind regards,
> Torbjörn
> 
> --
> 
> This patch introduces, optional, TLS (thread local storage) initialization to
> the startup code. It also brings in the same interface that is exposed to the
> application from picolibc so that an application can initialize additional
> blocks as needed and switch to them when switching tasks.
> 
> The picolibc sources are kept as-is except for:
> 
> - _BEGIN_STD_C -> __BEGIN_DECLS
> - _END_STD_C -> __END_DECLS
> - #include <picolibc.h> -> #include <newlib.h>
> 
> Origin of the code is picolibc-1.8.12.
> 
> This new feature is activated by --enable-newlib-thread-local-storage.
> 
> Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
> ---
>   libgloss/arm/crt0.S                  | 13 ++++
>   newlib/configure                     | 21 ++++++
>   newlib/configure.ac                  | 13 ++++
>   newlib/libc/include/picotls.h        | 76 +++++++++++++++++++++
>   newlib/libc/machine/arm/Makefile.inc |  1 +
>   newlib/libc/machine/arm/arm_tls.h    | 60 +++++++++++++++++
>   newlib/libc/machine/arm/read_tp.S    | 98 ++++++++++++++++++++++++++++
>   newlib/libc/machine/arm/set_tls.c    | 79 ++++++++++++++++++++++
>   newlib/libc/machine/arm/tls.c        | 52 +++++++++++++++
>   newlib/libc/misc/Makefile.inc        |  1 +
>   newlib/libc/misc/inittls.c           | 77 ++++++++++++++++++++++
>   newlib/libc/sys/arm/crt0.S           | 13 ++++
>   newlib/newlib.hin                    |  6 ++
>   13 files changed, 510 insertions(+)
>   create mode 100644 newlib/libc/include/picotls.h
>   create mode 100644 newlib/libc/machine/arm/arm_tls.h
>   create mode 100644 newlib/libc/machine/arm/read_tp.S
>   create mode 100644 newlib/libc/machine/arm/set_tls.c
>   create mode 100644 newlib/libc/machine/arm/tls.c
>   create mode 100644 newlib/libc/misc/inittls.c
> 
> diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S
> index b9e768007..81033a3b2 100644
> --- a/libgloss/arm/crt0.S
> +++ b/libgloss/arm/crt0.S
> @@ -388,6 +388,15 @@ __change_mode:
>   #endif
>   	
>   	bl	FUNCTION (memset)
> +
> +#ifdef __THREAD_LOCAL_STORAGE
> +    /* Initialize TLS in local-exec mode.  */
> +	ldr	a1, .LCtls_base	/* First arg: TLS block.  */
> +	bl	FUNCTION (_init_tls)
> +	ldr	a1, .LCtls_base	/* First arg: TLS block.  */
> +	bl	FUNCTION (_set_tls)
> +#endif
> +
>   #if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
>   /* Changes by toralf: Taken from libgloss/m68k/crt0.S
>      initialize target specific stuff. Only execute these
> @@ -607,6 +616,10 @@ change_back:
>   	.word	__bss_start__
>   .LC2:
>   	.word	__bss_end__
> +#ifdef __THREAD_LOCAL_STORAGE
> +.LCtls_base:
> +	.word	__tls_base
> +#endif
>   #ifdef __USES_INITFINI__
>   #ifdef _LITE_EXIT
>   .Latexit:
> diff --git a/newlib/configure b/newlib/configure
> index ab31510aa..0ff110a7c 100755
> --- a/newlib/configure
> +++ b/newlib/configure
> @@ -988,6 +988,7 @@ enable_newlib_global_atexit
>   enable_newlib_reent_small
>   enable_newlib_reent_binary_compat
>   enable_newlib_reent_thread_local
> +enable_newlib_thread_local_storage
>   enable_newlib_global_stdio_streams
>   enable_newlib_fvwrite_in_streamio
>   enable_newlib_fseek_optimization
> @@ -1659,6 +1660,7 @@ Optional Features:
>     --enable-newlib-reent-small   enable small reentrant struct support
>     --enable-newlib-reent-binary-compat   enable backward binary compatibility for struct _reent
>     --enable-newlib-reent-thread-local   enable thread-local storage objects as a replacment for struct _reent members
> +  --enable-newlib-thread-local-storage enable the TLS runtime API
>     --enable-newlib-global-stdio-streams   enable global stdio streams
>     --disable-newlib-fvwrite-in-streamio    disable iov in streamio
>     --disable-newlib-fseek-optimization    disable fseek optimization
> @@ -2437,6 +2439,17 @@ else
>     newlib_reent_thread_local=no
>   fi
>   
> +# Check whether --enable-newlib-thread-local-storage was given.
> +if test "${enable_newlib_thread_local_storage+set}" = set; then :
> +  enableval=$enable_newlib_thread_local_storage; case "${enableval}" in
> +  yes) newlib_thread_local_storage=yes ;;
> +  no)  newlib_thread_local_storage=no ;;
> +  *) as_fn_error $? "bad value ${enableval} for newlib-thread-local-storage option" "$LINENO" 5 ;;
> + esac
> +else
> +  newlib_thread_local_storage=no
> +fi
> +
>   # Check whether --enable-newlib-global-stdio-streams was given.
>   if test "${enable_newlib_global_stdio_streams+set}" = set; then :
>     enableval=$enable_newlib_global_stdio_streams; case "${enableval}" in
> @@ -6603,6 +6616,14 @@ $as_echo "#define _WANT_REENT_THREAD_LOCAL 1" >>confdefs.h
>   
>   fi
>   
> +if test "${newlib_thread_local_storage}" = "yes"; then
> +
> +$as_echo "#define __THREAD_LOCAL_STORAGE 1" >>confdefs.h
> +
> +$as_echo "#define __THREAD_LOCAL_STORAGE_API 1" >>confdefs.h
> +
> +fi
> +
>   _mb_len_max=1
>   if test "${newlib_mb}" = "yes"; then
>   
> diff --git a/newlib/configure.ac b/newlib/configure.ac
> index a4807830e..0ade683a8 100644
> --- a/newlib/configure.ac
> +++ b/newlib/configure.ac
> @@ -187,6 +187,14 @@ AC_ARG_ENABLE(newlib-reent-thread-local,
>     esac
>    fi], [newlib_reent_thread_local=no])dnl
>   
> +AC_ARG_ENABLE(newlib-thread-local-storage,
> +[  --enable-newlib-thread-local-storage enable the TLS runtime API],
> +[case "${enableval}" in
> +  yes) newlib_thread_local_storage=yes ;;
> +  no)  newlib_thread_local_storage=no ;;
> +  *)   AC_MSG_ERROR(bad value ${enableval} for newlib-thread-local-storage option) ;;
> + esac], [newlib_thread_local_storage=no])dnl
> +
>   dnl Support --enable-newlib-global-stdio-streams
>   dnl This is no longer optional.  It is enabled in all Newlib configurations.
>   AC_ARG_ENABLE(newlib-global-stdio-streams,
> @@ -478,6 +486,11 @@ if test "${newlib_reent_thread_local}" = "yes"; then
>     AC_DEFINE(_WANT_REENT_THREAD_LOCAL, 1, [Define to enable thread-local storage objects as a replacment for struct _reent members.])
>   fi
>   
> +if test "${newlib_thread_local_storage}" = "yes"; then
> +  AC_DEFINE(__THREAD_LOCAL_STORAGE, 1, [Define to enable the TLS runtime API.])
> +  AC_DEFINE(__THREAD_LOCAL_STORAGE_API, 1, [Define to enable the TLS runtime API.])
> +fi
> +
>   _mb_len_max=1
>   if test "${newlib_mb}" = "yes"; then
>     AC_DEFINE(_MB_CAPABLE, 1, [Multibyte supported.])
> diff --git a/newlib/libc/include/picotls.h b/newlib/libc/include/picotls.h
> new file mode 100644
> index 000000000..e87f0b58a
> --- /dev/null
> +++ b/newlib/libc/include/picotls.h
> @@ -0,0 +1,76 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright © 2019 Keith Packard
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above
> + *    copyright notice, this list of conditions and the following
> + *    disclaimer in the documentation and/or other materials provided
> + *    with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _PICOTLS_H_
> +#define _PICOTLS_H_
> +
> +#include <sys/cdefs.h>
> +
> +#ifdef __THREAD_LOCAL_STORAGE
> +
> +#include <sys/types.h>
> +
> +__BEGIN_DECLS
> +
> +extern char __tls_size[];
> +
> +static inline size_t
> +_tls_size(void)
> +{
> +    return (size_t)(uintptr_t)__tls_size;
> +}
> +
> +extern char __tls_align[];
> +
> +static inline size_t
> +_tls_align(void)
> +{
> +    return (size_t)(uintptr_t)__tls_align;
> +}
> +
> +/*
> + * Initialize a TLS block, copying the data segment from flash and
> + * zeroing the BSS segment.
> + */
> +void _init_tls(void *tls);
> +
> +/* Set the TLS pointer to the specific block */
> +void _set_tls(void *tls);
> +
> +__END_DECLS
> +
> +#endif
> +
> +#endif /* _PICOTLS_H_ */
> diff --git a/newlib/libc/machine/arm/Makefile.inc b/newlib/libc/machine/arm/Makefile.inc
> index 2d6c08d71..253e54620 100644
> --- a/newlib/libc/machine/arm/Makefile.inc
> +++ b/newlib/libc/machine/arm/Makefile.inc
> @@ -3,6 +3,7 @@ libc_a_SOURCES += \
>   	%D%/aeabi_memcpy.c %D%/aeabi_memcpy-armv7a.S \
>   	%D%/aeabi_memmove.c %D%/aeabi_memmove-soft.S \
>   	%D%/aeabi_memset.c %D%/aeabi_memset-soft.S %D%/aeabi_memclr.c \
> +	%D%/tls.c %D%/set_tls.c %D%/read_tp.S \
>   	%D%/memchr-stub.c \
>   	%D%/memchr.S \
>   	%D%/memcpy-stub.c \
> diff --git a/newlib/libc/machine/arm/arm_tls.h b/newlib/libc/machine/arm/arm_tls.h
> new file mode 100644
> index 000000000..0a7421d68
> --- /dev/null
> +++ b/newlib/libc/machine/arm/arm_tls.h
> @@ -0,0 +1,60 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright © 2020 Keith Packard
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above
> + *    copyright notice, this list of conditions and the following
> + *    disclaimer in the documentation and/or other materials provided
> + *    with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#if ((__ARM_FEATURE_COPROC & 1) || __ARM_ARCH >= 8) && __ARM_ARCH_PROFILE != 'M' && __ARM_ARCH >= 6
> +#define ARM_TLS_CP15
> +#endif
> +
> +/* Switch cortex-m0 to use RP2040 CPUID register if requested */
> +#ifdef __THREAD_LOCAL_STORAGE_RP2040
> +#define ARM_RP2040
> +#endif
> +
> +#ifdef ARM_RP2040
> +#define RP2040_SIO_BASE 0xd0000000
> +#define RP2040_CPUID    (RP2040_SIO_BASE + 0)
> +#define ARM_TLS_COUNT   2
> +#else
> +#define ARM_TLS_COUNT 1
> +#endif
> +
> +#ifndef _IN_ASM
> +/* This needs to be global so that __aeabi_read_tp can
> + * refer to it in an asm statement
> + */
> +#ifndef ARM_TLS_CP15
> +extern void *__tls[ARM_TLS_COUNT];
> +#endif
> +#endif
> diff --git a/newlib/libc/machine/arm/read_tp.S b/newlib/libc/machine/arm/read_tp.S
> new file mode 100644
> index 000000000..811e073f8
> --- /dev/null
> +++ b/newlib/libc/machine/arm/read_tp.S
> @@ -0,0 +1,98 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright © 2020 Keith Packard
> + * Copyright © 2024 Stephen Street
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above
> + *    copyright notice, this list of conditions and the following
> + *    disclaimer in the documentation and/or other materials provided
> + *    with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +#include <newlib.h>
> +
> +#ifdef __THREAD_LOCAL_STORAGE
> +
> +#define _IN_ASM
> +#include "arm_tls.h"
> +/*
> + * This cannot be a C ABI function as the compiler assumes that it
> + * does not modify anything other than r0 and lr.
> + */
> +	.syntax unified
> +	.section .text.__aeabi_read_tp
> +	.align 4
> +	.p2align 4,,15
> +	.global __aeabi_read_tp
> +	.type __aeabi_read_tp,%function
> +#ifdef __thumb__
> +	.thumb
> +#endif
> +
> +__aeabi_read_tp:
> +	.cfi_sections .debug_frame
> +	.cfi_startproc
> +
> +#ifdef ARM_TLS_CP15
> +	mrc p15, 0, r0, c13, c0, 3
> +	bx lr
> +#else
> +
> +#ifdef ARM_RP2040
> +
> +	/*
> +	 * Code for RP2040 processor. This is a dual-core cortex-m0
> +	 * design. We use the CPUID register, stored at offset zero of
> +	 * the Single-cycle IO block at 0xd0000000
> +	 */
> +
> +#define TLS_SIZE	(4 * RP2040_NCORE)
> +
> +	push {r1,lr}		/* Save R1 (and LR) */
> +	ldr r1,=0xd0000000	/* Address of SIO->CPUID */
> +	ldr r1,[r1]	   	/* Fetch active core */
> +	lsls r1,r1,#2	   	/* Multiply by 4 */
> +	ldr r0,=__tls		/* Address of __tls array */
> +	ldr r0,[r0,r1]		/* Fetch __tls[CPUID] */
> +	pop {r1,pc}		/* Restore R1 and return  */
> +
> +#else
> +
> +#define TLS_SIZE	4
> +
> +	ldr r0,=__tls		/* Load the address of __tls */
> +	ldr r0,[r0]		/* Dereference to get the value of __tls */
> +	bx lr			/* All done, return to caller */
> +
> +#endif
> +
> +#endif
> +
> +	.cfi_endproc
> +
> +#endif
> +
> diff --git a/newlib/libc/machine/arm/set_tls.c b/newlib/libc/machine/arm/set_tls.c
> new file mode 100644
> index 000000000..fd3e940f6
> --- /dev/null
> +++ b/newlib/libc/machine/arm/set_tls.c
> @@ -0,0 +1,79 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright © 2019 Keith Packard
> + * Copyright © 2024 Stephen Street
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above
> + *    copyright notice, this list of conditions and the following
> + *    disclaimer in the documentation and/or other materials provided
> + *    with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <picotls.h>
> +#include <string.h>
> +#include <stdint.h>
> +
> +#ifdef __THREAD_LOCAL_STORAGE_API
> +
> +#include "arm_tls.h"
> +
> +/* This needs to be global so that __aeabi_read_tp can
> + * refer to it in an asm statement
> + */
> +#ifndef ARM_TLS_CP15
> +extern void *__tls[];
> +#endif
> +
> +/* The size of the thread control block.
> + * TLS relocations are generated relative to
> + * a location this far *before* the first thread
> + * variable (!)
> + * NB: The actual size before tp also includes padding
> + * to align up to the alignment of .tdata/.tbss.
> + */
> +#define TCB_SIZE 8
> +extern char __arm32_tls_tcb_offset;
> +#define TP_OFFSET ((size_t)&__arm32_tls_tcb_offset)
> +
> +void
> +_set_tls(void *tls)
> +{
> +    tls = (uint8_t *)tls - TP_OFFSET;
> +#ifdef ARM_TLS_CP15
> +    __asm__("mcr p15, 0, %0, cr13, cr0, 3" : : "r"(tls));
> +#else
> +#ifdef ARM_RP2040
> +    uint32_t cpuid = *(uint32_t *)0xd0000000;
> +    __tls[cpuid] = tls;
> +#else
> +    __tls[0] = tls;
> +#endif
> +#endif
> +}
> +
> +#endif
> diff --git a/newlib/libc/machine/arm/tls.c b/newlib/libc/machine/arm/tls.c
> new file mode 100644
> index 000000000..156b9d72a
> --- /dev/null
> +++ b/newlib/libc/machine/arm/tls.c
> @@ -0,0 +1,52 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright © 2019 Keith Packard
> + * Copyright © 2024 Stephen Street
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above
> + *    copyright notice, this list of conditions and the following
> + *    disclaimer in the documentation and/or other materials provided
> + *    with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <picotls.h>
> +#include <string.h>
> +#include <stdint.h>
> +
> +#ifdef __THREAD_LOCAL_STORAGE
> +
> +#include "arm_tls.h"
> +
> +/* This needs to be global so that __aeabi_read_tp can
> + * refer to it in an asm statement
> + */
> +#ifndef ARM_TLS_CP15
> +void *__tls[ARM_TLS_COUNT];
> +#endif
> +
> +#endif
> diff --git a/newlib/libc/misc/Makefile.inc b/newlib/libc/misc/Makefile.inc
> index 78bb022dd..1abd05295 100644
> --- a/newlib/libc/misc/Makefile.inc
> +++ b/newlib/libc/misc/Makefile.inc
> @@ -2,6 +2,7 @@ libc_a_SOURCES += \
>   	%D%/__dprintf.c \
>   	%D%/unctrl.c \
>   	%D%/ffs.c \
> +	%D%/inittls.c \
>   	%D%/init.c \
>   	%D%/fini.c
>   
> diff --git a/newlib/libc/misc/inittls.c b/newlib/libc/misc/inittls.c
> new file mode 100644
> index 000000000..458013fbb
> --- /dev/null
> +++ b/newlib/libc/misc/inittls.c
> @@ -0,0 +1,77 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright © 2019 Keith Packard
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above
> + *    copyright notice, this list of conditions and the following
> + *    disclaimer in the documentation and/or other materials provided
> + *    with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <picotls.h>
> +#include <string.h>
> +#include <stdint.h>
> +
> +#ifdef __THREAD_LOCAL_STORAGE_API
> +
> +/*
> + * The TLS block consists of initialized data immediately followed by
> + * zero filled data
> + *
> + * These addresses must be defined by the loader configuration file
> + */
> +
> +extern char __tdata_source[]; /* Source of TLS initialization data (in ROM) */
> +
> +#ifdef __PICOCRT_RUNTIME_SIZE
> +extern char __tdata_start[]; /* Start of static tdata area */
> +extern char __tdata_end[];   /* End of static tdata area */
> +extern char __tbss_start[];  /* Start of static zero-initialized TLS data */
> +extern char __tbss_end[];    /* End of static zero-initialized TLS data */
> +#define __tdata_size  (__tdata_end - __tdata_start)
> +#define __tbss_size   (__tbss_end - __tbss_start)
> +#define __tbss_offset (__tbss_start - __tdata_start)
> +#else
> +extern char __tdata_size[];  /* Size of TLS initized data */
> +extern char __tbss_size[];   /* Size of TLS zero-filled data */
> +extern char __tbss_offset[]; /* Offset from tdata to tbss */
> +#endif
> +
> +void
> +_init_tls(void *__tls)
> +{
> +    char *tls = __tls;
> +
> +    /* Copy tls initialized data */
> +    memcpy(tls, __tdata_source, (uintptr_t)__tdata_size);
> +
> +    /* Clear tls zero data */
> +    memset(tls + (uintptr_t)__tbss_offset, '\0', (uintptr_t)__tbss_size);
> +}
> +
> +#endif
> diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S
> index 51e86d549..ea2122d93 100644
> --- a/newlib/libc/sys/arm/crt0.S
> +++ b/newlib/libc/sys/arm/crt0.S
> @@ -375,6 +375,15 @@ __change_mode:
>   #endif
>   	
>   	bl	FUNCTION (memset)
> +
> +#ifdef __THREAD_LOCAL_STORAGE
> +    /* Initialize TLS in local-exec mode.  */
> +	ldr	a1, .LCtls_base	/* First arg: TLS block.  */
> +	bl	FUNCTION (_init_tls)
> +	ldr	a1, .LCtls_base	/* First arg: TLS block.  */
> +	bl	FUNCTION (_set_tls)
> +#endif
> +
>   #if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
>   /* Changes by toralf: Taken from libgloss/m68k/crt0.S
>      initialize target specific stuff. Only execute these
> @@ -598,6 +607,10 @@ change_back:
>   	.word	__bss_start__
>   .LC2:
>   	.word	__bss_end__
> +#ifdef __THREAD_LOCAL_STORAGE
> +.LCtls_base:
> +	.word	__tls_base
> +#endif
>   #ifdef __USES_INITFINI__
>   #ifdef _LITE_EXIT
>   .Latexit:
> diff --git a/newlib/newlib.hin b/newlib/newlib.hin
> index 52cd500db..350762f2f 100644
> --- a/newlib/newlib.hin
> +++ b/newlib/newlib.hin
> @@ -420,6 +420,12 @@
>      _reent members. */
>   #undef _WANT_REENT_THREAD_LOCAL
>   
> +/* Define to enable the TLS runtime API. */
> +#undef __THREAD_LOCAL_STORAGE
> +
> +/* Define to enable the TLS runtime API. */
> +#undef __THREAD_LOCAL_STORAGE_API
> +
>   /* Register application finalization function using atexit. */
>   #undef _WANT_REGISTER_FINI
>   



More information about the Newlib mailing list