[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