Skip to content

Latest commit

 

History

History
59 lines (44 loc) · 2.33 KB

init.md

File metadata and controls

59 lines (44 loc) · 2.33 KB

Initializers/Constructors and Finalizers/Destructors in Picolibc

The __libc_init_array and __libc_fini_array functions in Picolibc are called by Picocrt during application startup and shutdown. If you have custom start up code that replaces Picocrt, you probably want to call these as well.

__libc_init_array

This function performs application initialization by calling:

  1. Functions listed in the preinit array
  2. _init function
  3. Functions listed in the init array

_init function

Your program may declare an optional initialization function called _init. If such a function is included in the binary it will be called before the init array contents are evaluated.

__libc_fini_array

Most embedded applications never return from main, but if yours does, Picocrt will call:

  1. Functions listed in the fini array
  2. _fini function

_fini function

Your program may declare an optional finalization function called _fini. If such a function is included in the binary it will be called after the fini array contents are evaluated.

Automatically generated arrays of function pointers

The .preinit_array, .init_array and .fini_array segments are built by the linker using data generated by the compiler. When you decorate a function with __attribute__((constructor)), the compiler places the address of the function into the .init_array segment. Decorate a function with __attribute__((destructor)) and the compiler will place its address in the .fini_array segment. The .preinit_array segment is generated internally by the compiler for things like C++ vtable validation

The linker script should collect all of the data from these segments into memory (probably flash as it doesn't change) so that the image ends up with arrays of function pointers. For data from the .init_array segment, the array should start with the symbol __init_array_start and ending with __init_array_end. For data from the .fini_array segment, the array should start with the symbol __fini_array_start and end with __fini_array_end. Finally, for data from the .preinit_array segment, the array starts with __preinit_array_start and ends with __preinit_array_end.

Each of these arrays are complicated by the optional priority assigned to destructors and constructors, and the presense of the deprecated .ctors and .dtors segments.