I have some simple declarations of a global instances with non-empty constructors. These constructors are called during startup automatically. I am cross-compiling C++ on Linux to different microcontroller targets.
As for
calls to constructors are put into the .init_array section. The map file looks like this:
.init_array 0x00007cb8 0x4 libmotor.o
.init_array 0x00007cbc 0x4 libaudio.o
As for
these calls get into the .ctors section:
.ctors 0x000000009d011508 0x4 libmotor.o
.ctors 0x000000009d01150c 0x4 libaudio.o
Compiling was done with -ffunction-sections -fdata-sections, the linker got --gc-sections.
All binaries work, but I'd like to put all calls into the same section (to simplify maintenance of linker scripts).
Global constructors are called after initialization of other global variables and before the main() function is called. Global destructors are invoked during the exit run-time support function, similar to functions registered through atexit. Section 8.9. 2.6 discusses the format of the global constructor table.
A section is set aside for a list of constructors, and another for a list of destructors. Traditionally these are called ' . ctors ' and ' . dtors '. Each object file that defines an initialization function also puts a word in the constructor section to point to that function.
Sets both elements as static, the array in argv and the init_array. It will later check to make sure they match. It also takes more code than you should add to this kind of function to break this process or do anything other than what it is meant for which is to be left alone.
The syntax __attribute__((constructor)) is used to execute a function when the program starts. and the syntax __attribute__((destructor)) is used to execute the function when main() function is completed.
There is a long discussion in Bug 46770 - Replace .ctors/.dtors with .init_array/.fini_array on targets supporting them
I have extracted some items which explain the situation:
Why did .init_array turn up?
We added
.init_array/.fini_arrayin order to blend the SVR4 version of.init, which contained actual code, with the HP-UX version, which contained function pointers and used aDT_INIT_SZentry in the dynamic array rather than prologue and epilogue pieces contributed from crt*.o files. The HP-UX version was seen as an improvement, but it wasn't compatible, so we renamed the sections and the dynamic table entries so that the two versions could live side-by-side and implementations could transition slowly from one to the other.On HP-UX, we used
.init/.init_arrayfor static constructors, and they registered the corresponding static destructors on a specialatexitlist, rather than adding destructors to.fini_array, so that we could handle destructors ondlclose()events properly (subject to your interpretation of "properly" in that context)
The order of execution differs between .ctors and .init_array
Backwarding order of
.ctorssectionSome programs may implicitly rely on the fact that global constructors in archives linked later are run before constructors in the object linked against those archives. That is, given
g++ foo.o -lbarwhere bar is a static archive, not a shared library, then currently the global constructors in objects pulled in from libbar.c will be executed before the global constructors in foo.o. That was an intentional choice because it is more likely to be correct than the reverse. However, the C++ standard does not guarantee it, so any programs which relies on this ordering is technically invalid.
Problem of backwarding order of .ctors
A lot of work was done in both GNU
ldandgoldto move constructors from.ctorsto.init_array, all to improve startup latency for FirefoxUsing
.init_array/.fini_arrayinstead of.ctors/.dtorsremoves the need for the associated (relative) relocations, and avoids the backwards disk seeks on startup (since while.ctorsare processed backwards,.init_arrayis processed forward).
Transition from .ctors to .init_array
The mainline versions of both GNU
ldandgoldnow put.ctorssections into.init_arraysections, and put.dtorssections into.fini_arraysections.
Comment: Probably introduced with GCC 4.7.
ARM
ARM EABI has been using
.init_arrayfrom day one.
Comment: Nevertheless the default linker script contains a .ctors output section.
GCC configuration
One option you have is to configure gcc with --disable-initfini-array.
Comment: This option does not turn up in the output of mips-elf-gcc -v (-v shows "Configured with: ...").
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With