Skip to content

note for ATfE (clang) / picolibc #90

Description

@FabKlein

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions