diff --git a/src/rp2040/boot_stage2/CMakeLists.txt b/src/rp2040/boot_stage2/CMakeLists.txt index 2798b3640..eebfb600b 100644 --- a/src/rp2040/boot_stage2/CMakeLists.txt +++ b/src/rp2040/boot_stage2/CMakeLists.txt @@ -49,7 +49,9 @@ function(pico_define_boot_stage2 NAME SOURCES) if (PICO_C_COMPILER_IS_CLANG) target_link_options(${NAME} PRIVATE "-nostdlib") elseif (PICO_C_COMPILER_IS_GNU) - target_link_options(${NAME} PRIVATE "--specs=nosys.specs") + if (PICO_CLIB STREQUAL "newlib") + target_link_options(${NAME} PRIVATE "--specs=nosys.specs") + endif() target_link_options(${NAME} PRIVATE "-nostartfiles") endif () diff --git a/src/rp2350/boot_stage2/CMakeLists.txt b/src/rp2350/boot_stage2/CMakeLists.txt index fbf95b53a..446ca12aa 100644 --- a/src/rp2350/boot_stage2/CMakeLists.txt +++ b/src/rp2350/boot_stage2/CMakeLists.txt @@ -49,7 +49,9 @@ function(pico_define_boot_stage2 NAME SOURCES) if (PICO_C_COMPILER_IS_CLANG) target_link_options(${NAME} PRIVATE "-nostdlib") elseif (PICO_C_COMPILER_IS_GNU) - target_link_options(${NAME} PRIVATE "--specs=nosys.specs") + if (PICO_CLIB STREQUAL "newlib") + target_link_options(${NAME} PRIVATE "--specs=nosys.specs") + endif() target_link_options(${NAME} PRIVATE "-nostartfiles") endif () diff --git a/src/rp2_common/pico_clib_interface/picolibc_interface.c b/src/rp2_common/pico_clib_interface/picolibc_interface.c index 63d79135e..c82e2baaf 100644 --- a/src/rp2_common/pico_clib_interface/picolibc_interface.c +++ b/src/rp2_common/pico_clib_interface/picolibc_interface.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "pico.h" #if LIB_PICO_STDIO @@ -58,6 +59,12 @@ static FILE __stdio = FDEV_SETUP_STREAM(picolibc_putc, picolibc_flush, _FDEV_SETUP_RW); +#ifdef __GNUCLIKE_PRAGMA_DIAGNOSTIC +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wunknown-warning-option" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + FILE *const stdin = &__stdio; __strong_reference(stdin, stdout); __strong_reference(stdin, stderr); void __weak __assert_func(const char *file, int line, const char *func, const char *failedexpr) { @@ -129,26 +136,45 @@ void runtime_init(void) { __libc_init_array(); } -#if !PICO_RUNTIME_NO_INIT_PER_CORE_TLS_SETUP -__weak void runtime_init_pre_core_tls_setup(void) { - // for now we just set the same global area on both cores - // note: that this is superfluous with the stock picolibc it seems, since it is itself - // using a version of __aeabi_read_tp that returns the same pointer on both cores - extern char __tls_base[]; - extern void _set_tls(void *tls); - _set_tls(__tls_base); +/* 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. + */ +extern char __arm32_tls_tcb_offset; +#define TP_OFFSET ((size_t)&__arm32_tls_tcb_offset) + +static void *__tls[2]; + +void _set_tls(void *tls) { + tls = (uint8_t *)tls - TP_OFFSET; + __tls[get_core_num()] = tls; } -#endif -#if !PICO_RUNTIME_SKIP_INIT_PER_CORE_TLS_SETUP -PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_pre_core_tls_setup, PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP); -#endif +/* Initialized by the linker, one per core */ +extern char __tls0_base[], __tls1_base[]; +static void * const __tls_base[2] = { __tls0_base, __tls1_base }; + +void runtime_init_per_core_tls_setup(void) { + void *tls_base = __tls_base[get_core_num()]; + _init_tls(tls_base); + _set_tls(tls_base); +} -//// naked as it must preserve everything except r0 and lr -//uint32_t __attribute__((naked)) WRAPPER_FUNC(__aeabi_read_tp)() { -// // note for now we are just returning a shared instance on both cores -// pico_default_asm_volatile( -// "ldr r0, =__tls_base\n" -// "bx lr\n" -// ); -//} \ No newline at end of file +PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_per_core_tls_setup, PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP); + +uint32_t __aeabi_read_tp(void); + +uint32_t __attribute__((naked)) __aeabi_read_tp(void) { + pico_default_asm_volatile( + "push {r1,lr} /* Save R1 (and LR) */\n" + "ldr r1,=0xd0000000 /* Address of SIO->CPUID */\n" + "ldr r1,[r1] /* Fetch active core */\n" + "lsls r1,r1,#2 /* Multiply by 4 */\n" + "ldr r0,=%0 /* Address of __tls array */\n" + "ldr r0,[r0,r1] /* Fetch __tls[CPUID] */\n" + "pop {r1,pc} /* Restore R1 and return */\n" : : "i" (__tls) + ); +} diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld b/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld index 6f5000566..05c3560df 100644 --- a/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld +++ b/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -87,6 +89,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -98,6 +101,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -129,6 +133,30 @@ SECTIONS } > FLASH __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >FLASH + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >FLASH + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -177,37 +205,34 @@ SECTIONS . = ALIGN(4); } > RAM AT> FLASH - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH PROVIDE(__data_end__ = .); /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss (NOLOAD) : { . = ALIGN(4); - __tbss_end = .; - + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld b/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld index 842ebfd3c..75336feb3 100644 --- a/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld +++ b/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -86,6 +88,30 @@ SECTIONS } > FLASH __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >FLASH + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >FLASH + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -155,6 +181,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -166,6 +193,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -178,37 +206,34 @@ SECTIONS . = ALIGN(4); } > RAM AT> FLASH - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH PROVIDE(__data_end__ = .); /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss : { . = ALIGN(4); - __tbss_end = .; - + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_default.ld b/src/rp2_common/pico_crt0/rp2040/memmap_default.ld index 51254012d..d9b398cc8 100644 --- a/src/rp2_common/pico_crt0/rp2040/memmap_default.ld +++ b/src/rp2_common/pico_crt0/rp2040/memmap_default.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -87,6 +89,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -98,6 +101,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -129,6 +133,30 @@ SECTIONS } > FLASH __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >FLASH + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >FLASH + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -177,37 +205,34 @@ SECTIONS . = ALIGN(4); } > RAM AT> FLASH - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH PROVIDE(__data_end__ = .); /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss (NOLOAD) : { . = ALIGN(4); - __tbss_end = .; - + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; @@ -269,9 +294,6 @@ SECTIONS /* picolibc and LLVM */ PROVIDE (__heap_start = __end__); PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); /* llvm-libc */ PROVIDE (_end = __end__); diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld b/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld index dbf006a8c..8e18b1b2f 100644 --- a/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld +++ b/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -91,6 +93,30 @@ SECTIONS } > RAM __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >RAM + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >RAM + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -118,6 +144,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -129,6 +156,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -141,12 +169,6 @@ SECTIONS . = ALIGN(4); } > RAM - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM PROVIDE(__data_end__ = .); .uninitialized_data (NOLOAD): { @@ -156,26 +178,29 @@ SECTIONS /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss (NOLOAD) : { . = ALIGN(4); - __tbss_end = .; - + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; @@ -232,9 +257,6 @@ SECTIONS /* picolibc and LLVM */ PROVIDE (__heap_start = __end__); PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); /* llvm-libc */ PROVIDE (_end = __end__); diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld b/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld index 44c69f3b9..6ed8d1947 100644 --- a/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld +++ b/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -102,6 +104,30 @@ SECTIONS } > FLASH __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >FLASH + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >FLASH + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -173,6 +199,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -184,6 +211,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -196,31 +224,14 @@ SECTIONS . = ALIGN(4); } > RAM AT> FLASH - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH PROVIDE(__data_end__ = .); /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss : { . = ALIGN(4); - __tbss_end = .; - + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) PROVIDE(__global_pointer$ = . + 2K); @@ -229,6 +240,20 @@ SECTIONS __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_default.ld b/src/rp2_common/pico_crt0/rp2350/memmap_default.ld index bce316d14..c1f8856fe 100644 --- a/src/rp2_common/pico_crt0/rp2350/memmap_default.ld +++ b/src/rp2_common/pico_crt0/rp2350/memmap_default.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -77,6 +79,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -88,6 +91,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -141,6 +145,30 @@ SECTIONS } > FLASH __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >FLASH + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >FLASH + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -189,30 +217,14 @@ SECTIONS . = ALIGN(4); } > RAM AT> FLASH - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH PROVIDE(__data_end__ = .); /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss (NOLOAD) : { . = ALIGN(4); - __tbss_end = .; + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) @@ -222,6 +234,20 @@ SECTIONS __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld b/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld index 5bedf6d21..bd46e3a29 100644 --- a/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld +++ b/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld @@ -4,10 +4,12 @@ __exidx_end __etext __data_start__ + __bothinit_array_start __preinit_array_start __preinit_array_end __init_array_start __init_array_end + __bothinit_array_end __fini_array_start __fini_array_end __data_end__ @@ -93,6 +95,30 @@ SECTIONS } > RAM __exidx_end = .; + /* Assign TLS offsets and load TLS initialization data */ + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE( __tdata_end = . ); + } >FLASH + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >FLASH + + PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_start ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start ); + /* Machine inspectable binary information */ . = ALIGN(4); __binary_info_start = .; @@ -121,6 +147,7 @@ SECTIONS . = ALIGN(4); /* preinit data */ + PROVIDE_HIDDEN (__bothinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(SORT(.preinit_array.*))) KEEP(*(.preinit_array)) @@ -132,6 +159,7 @@ SECTIONS KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__bothinit_array_end = .); . = ALIGN(4); /* finit data */ @@ -142,37 +170,21 @@ SECTIONS *(.jcr) . = ALIGN(4); - } > RAM - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; } > RAM + PROVIDE(__data_end__ = .); .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - .bss (NOLOAD) : { . = ALIGN(4); - __tbss_end = .; - + __bss_start__ = .; *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) PROVIDE(__global_pointer$ = . + 2K); @@ -181,6 +193,20 @@ SECTIONS __bss_end__ = .; } > RAM + # Thread local storage static allocations, one per core + + .tls0 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls0_base = .); + . = . + __tls_size_align; + } > RAM + + .tls1 (NOLOAD) : { + . = ALIGN(__tls_align); + PROVIDE(__tls1_base = .); + . = . + __tls_size_align; + } > RAM + .heap (NOLOAD): { __end__ = .; diff --git a/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h b/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h index 7f24008a2..00083b95e 100644 --- a/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h +++ b/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h @@ -21,6 +21,9 @@ #if defined __GNUC__ #include +#ifdef __PICOLIBC__ +#define __printflike(a,b) __picolibc_format(printf,a,b) +#endif // note LLVM defines __GNUC__ #ifdef __clang__ #define PICO_C_COMPILER_IS_CLANG 1 diff --git a/src/rp2_common/pico_runtime/CMakeLists.txt b/src/rp2_common/pico_runtime/CMakeLists.txt index e190d5106..8afb233dc 100644 --- a/src/rp2_common/pico_runtime/CMakeLists.txt +++ b/src/rp2_common/pico_runtime/CMakeLists.txt @@ -46,7 +46,9 @@ endforeach() # todo is this correct/needed? if (PICO_C_COMPILER_IS_GNU) - target_link_options(pico_runtime INTERFACE "--specs=nosys.specs") + if (PICO_CLIB STREQUAL "newlib") + target_link_options(${NAME} PRIVATE "--specs=nosys.specs") + endif() elseif (PICO_C_COMPILER_IS_CLANG) # target_link_options(pico_runtime INTERFACE "-nostdlib") endif() diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index c16968bba..380618734 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -125,13 +125,13 @@ if (NOT TARGET pico_standard_link) set(PICO_FLASH_SIZE_BYTES_STRING "${PICO_FLASH_SIZE_BYTES}") configure_file(${CMAKE_CURRENT_LIST_DIR}/pico_flash_region.template.ld ${CMAKE_BINARY_DIR}/pico_flash_region.ld) # add include path for linker scripts - target_link_options(pico_standard_link INTERFACE "LINKER:-L${CMAKE_BINARY_DIR}") + target_link_options(pico_standard_link INTERFACE "-L${CMAKE_BINARY_DIR}") # LINKER script will be PICO_TARGET_LINKER_SCRIPT if set on target, or ${CMAKE_CURRENT_LIST_DIR}/memmap_foo.ld # if PICO_TARGET_BINARY_TYPE is set to foo on the target, otherwise ${CMAKE_CURRENT_LIST_DIR}/memmap_${PICO_DEFAULT_BINARY_TYPE).ld set(_LINKER_SCRIPT_EXPRESSION "$>,$,${PICO_LINKER_SCRIPT_PATH}/memmap_$,>,${PICO_DEFAULT_BINARY_TYPE},$>.ld>") target_link_options(pico_standard_link INTERFACE - "LINKER:--script=${_LINKER_SCRIPT_EXPRESSION}" + "-T${_LINKER_SCRIPT_EXPRESSION}" ) pico_add_link_depend(pico_standard_link ${_LINKER_SCRIPT_EXPRESSION}) unset(_LINKER_SCRIPT_EXPRESSION) @@ -191,4 +191,23 @@ if (NOT TARGET pico_standard_link) endif() endif() endif() + + # Convert pico-sdk printf variant selection into picolibc version + # when using pico_printf_compiler + + if (PICO_CLIB STREQUAL "picolibc") + if (RUNTIME_INCLUDE_PRINTF_MINIMAL) + target_link_options(pico_standard_link INTERFACE + $<$,pico_printf_compiler>:--printf=m>) + elseif (RUNTIME_INCLUDE_PRINTF_FLOAT) + # this is the default + elseif (RUNTIME_INCLUDE_PRINTF_LONG_LONG) + target_link_options(pico_standard_link INTERFACE + $<$,pico_printf_compiler>:--printf=l>) + else() + target_link_options(pico_standard_link INTERFACE + $<$,pico_printf_compiler>:--printf=i>) + endif() + endif() + endif()