When using Arm Toolchain for Embedded (ATfE) with picolibc, it would be useful
to document the following linker-script requirement to avoid not-so-easy-to-debug
issues with CMSIS-Compiler retargeting.
If stdin/stdout are initialized from a registered constructor, e.g:
__attribute__((constructor(255)))
void platform_init(void) {
#ifdef RTE_CMSIS_Compiler_STDOUT_Custom
extern void stdout_init(void);
stdout_init();
#endif
}
the Clang linker script needs to provide the picolibc _bothinit_array*
symbols around the preinit/init-array region:
PROVIDE_HIDDEN(__bothinit_array_start = .);
PROVIDE_HIDDEN(__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN(__preinit_array_end = .);
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array .ctors))
PROVIDE_HIDDEN(__init_array_end = .);
PROVIDE_HIDDEN(__bothinit_array_end = .);
Could the CMSIS-Compiler documentation add a note for CLANG/picolibc users that
linker scripts must provide __bothinit_array_start and
__bothinit_array_end when constructor/init-array based initialization is used?
This is easy to miss because the CMSIS-Compiler retarget example calls
stdout_init() directly from main(), so the example does not expose the
problem. Projects that initialize CMSIS-Compiler streams from platform
constructors can fail silently.
ref:
https://developer.arm.com/documentation/107976/22-1-0/C-and-C---libraries/picolibc-C-runtime
AC6/GCC are more immune because:
- AC6 uses the Arm runtime initialization conventions.
- GCC/newlib uses the usual _preinit_array* and _init_array* symbols,
which were already present in default linker scripts.
When using Arm Toolchain for Embedded (ATfE) with picolibc, it would be useful
to document the following linker-script requirement to avoid not-so-easy-to-debug
issues with CMSIS-Compiler retargeting.
If stdin/stdout are initialized from a registered constructor, e.g:
the Clang linker script needs to provide the picolibc _bothinit_array*
symbols around the preinit/init-array region:
Could the CMSIS-Compiler documentation add a note for CLANG/picolibc users that
linker scripts must provide
__bothinit_array_startand__bothinit_array_endwhen constructor/init-array based initialization is used?This is easy to miss because the CMSIS-Compiler retarget example calls
stdout_init()directly frommain(), so the example does not expose theproblem. Projects that initialize CMSIS-Compiler streams from platform
constructors can fail silently.
ref:
https://developer.arm.com/documentation/107976/22-1-0/C-and-C---libraries/picolibc-C-runtime
AC6/GCC are more immune because:
which were already present in default linker scripts.