Fixes #2839 Picolibc compatibility issues#2840
Fixes #2839 Picolibc compatibility issues#2840keith-packard wants to merge 6 commits intoraspberrypi:developfrom
Conversation
| __libc_init_array(); | ||
| } | ||
|
|
||
| #if !PICO_RUNTIME_NO_INIT_PER_CORE_TLS_SETUP |
There was a problem hiding this comment.
The complete removal of these #if directives seems a bit odd?
There was a problem hiding this comment.
I wasn't sure how these symbols could ever be defined so that I could test to make sure the code operated when set.
There was a problem hiding this comment.
I dunno if it helps answer your question, but see sections 5.5.19. and 6.1. of https://pip.raspberrypi.com/documents/RP-009085-KB
If that doesn't help (I'm afraid the code here is beyond my level of knowledge), then you'll have to wait until somebody else has time to look at this.
(The reason I found the removal of these directives surprising, is because I'm sure they must have been added for a good reason 😉 )
There was a problem hiding this comment.
Pretty sure they were added because there wasn't any per-core TLS support in pico-sdk before I copied bits over from picolibc's implementation (which is only available when you build picolibc from source; I haven't figured out a good way to expose it without that).
There was a problem hiding this comment.
Ahh, a git grep reveals that these are indeed only used by the picolibc's bindings:
$ git grep PER_CORE_TLS_SETUP
src/rp2_common/pico_clib_interface/picolibc_interface.c:#if !PICO_RUNTIME_NO_INIT_PER_CORE_TLS_SETUP
src/rp2_common/pico_clib_interface/picolibc_interface.c:#if !PICO_RUNTIME_SKIP_INIT_PER_CORE_TLS_SETUP
src/rp2_common/pico_clib_interface/picolibc_interface.c:PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_pre_core_tls_setup, PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP);
src/rp2_common/pico_runtime_init/include/pico/runtime_init.h:// PICO_RUNTIME_SKIP_INIT_PER_CORE_TLS_SETUP defaults to 0
src/rp2_common/pico_runtime_init/include/pico/runtime_init.h:#ifndef PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP
src/rp2_common/pico_runtime_init/include/pico/runtime_init.h:#define PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP "10060"I was mistakenly assuming that this was some kind of "standard feature" that all C-lib bindings were expected to support 🤦
b03b963 to
71e8f79
Compare
71e8f79 to
a1e92a2
Compare
| /* 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 |
There was a problem hiding this comment.
What is the reason behind moving these sections to FLASH rather than keeping them in RAM?
There was a problem hiding this comment.
.tdata needs to be in FLASH so that it's initial contents are available to use in initializing TLS areas, .tbss needs to be sequential in addressing with .tdata so that the thread local offsets computed by the linker are correct. .tbss should not actually allocate any space in FLASH; the addresses generated are used only to compute TLS offsets during relocation. RAM for each of the per-core TLS areas is allocated below.
The previous kludge avoided the need to even initialize the TLS area by wedging it between .data and .bss and using the existing initializers of those to also initialize the TLS area. That relied upon careful layout of the TLS area to account for padding and alignment constraints, which are not entirely correct in the existing scripts.
The new way introduced here is far more traditional, with the exception of the static allocation of two TLS blocks in RAM.
|
where can we get/build a GCC compiler that uses picolibc to test with? |
|
@keith-packard can we split the tls stuff into a separate PR - it is going to clash with some other PRs. |
You can either use the current debian unstable toolchain for arm-none-eabi for which picolibc is the only supported C library, or you can use the debian stable toolchain and add the picolibc package. For the latter, you must build and link with --specs=picolibc.specs. In either case, For other systems, you can use the Zephyr SDK toolchain which is available for Linux, Mac OS X and Windows. You can also use the ARM GNU Toolchain version 15.2.rel1 and add the pre-built picolibc add-ons available here: https://github.com/picolibc/picolibc/releases/download/1.8.11/picolibc-arm-none-eabi-1.8.11-15.2.rel1.zip However, this toolchain is flawed in disabling TLS usage entirely, so I recommend against it. The current debian toolchain uses the same sources with slightly different configuration to enable TLS and use picolibc by default. |
nosys.specs controls how newlib performs linking, so it's not relevant to other C libraries. Signed-off-by: Keith Packard <keithp@keithp.com>
Picolibc doesn't provide __printflike, instead it provides a more general __picolibc_format for either scanf or printf. Use that to define our own __printflike version. Signed-off-by: Keith Packard <keithp@keithp.com> Gbp-Pq: Name 0005-pico_platform_compiler-Picolibc-compatibility-fix.patch
The kitchen_sink test enables -Wredundant-decls which generates a warning about the stdout and stderr alias definitions. Disable the warning as it is incorrect in this case. Signed-off-by: Keith Packard <keithp@keithp.com>
Using -Wl,--script= hides this option from the compiler driver causing it to insert it's own linker script when it uses picolibc. Using the -T option asks it to skip adding its own. Signed-off-by: Keith Packard <keithp@keithp.com>
Picolibc may combine the preinit and init arrays into a single list, in which case it will use __bothinit_array_start and __bothinit_array_end symbols instead of the separate __preinit_array_start, __preinit_array_end and __init_array_start, __init_array_end pairs. Define both so that either method works. Signed-off-by: Keith Packard <keithp@keithp.com>
When using pico_printf_compiler with picolibc, map the various RUNTIME_INCLUDE_PRINTF_* options into the matching picolibc link flags. Signed-off-by: Keith Packard <keithp@keithp.com>
a1e92a2 to
b068581
Compare
Can do. I've posted a separate PR which stacks the TLS changes atop the rest of these so they don't get lost. #2846 |
|
for what it's worth, i could successfully use this branch to compile using the picolibc based toolchain https://wonderful.asie.pl/, (only things i had to do were explicitly set the libc to use in the cmake and toolchain path) |
As a part of the Debian migration from newlib to picolibc for the arm-none-eabi GCC toolchain, a number of picolibc portability issues were discovered in pico-sdk. Here's a set of fixes that allows use of pico-sdk with picolibc 1.8.11.
__printflikein terms of__picolibc_format-Wl,--script=to-Twhen building a linker command line; this avoids referencing picolibc's default linker script. The alternative here would be to add-T/dev/nullwhen using picolibc; other projects have done that to allow continued use ofLINKER:--scriptfor compatibility with toolchains which don't support-T(I'm not sure which ones those might be).__bothinit_array_startand__bothinit_array_endto all of the linker scripts to allow picolibc's__libc_init_arrayfunction to correctly call constructors.A separate PR which stacks an implementation of per-core thread local variables is available as #2846