understanding the __libc_init_array

elf, gcc, linker-scripts, newlib, startup

Solution

These symbols are related to the C / C++ constructor and destructor startup and tear down code that is called before / after `main()`. Sections named `.init`, `.ctors`, `.preinit_array`, and `.init_array` are to do with initialization of C/C++ objects, and sections `.fini`, `.fini_array`, and `.dtors` are for tear down. The start and end symbols define the beginning and end of code sections related to such operations and might be referenced from other parts of the runtime support code.

The `.preinit_array` and `.init_array` sections contain arrays of pointers to functions that will be called on initialization. The `.fini_array` is an array of functions that will be called on destruction. Presumably the start and end labels are used to walk these lists.

A good example of code that uses these symbols is to be found here libc source for `initfini.c`. You can see that on startup, `__libc_init_array()` is called and this first calls all the function pointers in section `.preinit_array` by referring to the start and end labels. Then it calls the `_init()` function in the `.init` section. Lastly it calls all the function pointers in section `.init_array`. After `main()` is complete the teardown call to `__libc_fini_array()` causes all the functions in `.fini_array` to be called, before finally calling `_fini()`. Note that there seems to be a cut-and-paste bug in this code when it calculates the count of functions to call at teardown. Presumably they were dealing with a real time micro controller OS and never encountered this section.

Problem

I viewed the source code of __libc_init_array from http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.html . But I don't quite understand what this function does. I know that these symbols ``` /* These magic symbols are provided by the linker. */ extern void (*__preinit_array_start []) (void) __attribute__((weak)); extern void (*__preinit_array_end []) (void) __attribute__((weak)); extern void (*__init_array_start []) (void) __attribute__((weak)); extern void (*__init_array_end []) (void) __attribute__((weak)); extern void (*__fini_array_start []) (void) __attribute__((weak)); extern void (*__fini_array_end []) (void) __attribute__((weak)); ``` is defined in the linker script. Part of the linker script may look like: ``` .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH ... ``` and then I searched with the key "init_array" in the docs of ELF-v1.1, gcc 4.7.2, ld, and codesourcery(I'm using codesourcery g++ lite) only to get nothing. Where can I find the specification of these symbols?

Original source