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_array
in order to blend the SVR4 version of .init
, which contained actual code, with the HP-UX version, which contained function pointers and used a DT_INIT_SZ
entry 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_array
for static constructors, and they registered the corresponding static destructors on a special atexit
list, rather than adding destructors to .fini_array
, so that we could handle destructors on dlclose()
events properly (subject to your interpretation of "properly" in that context)
The order of execution differs between .ctors
and .init_array
Backwarding order of .ctors
section
Some 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 -lbar
where 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 ld
and gold
to move constructors from .ctors
to .init_array
, all to improve startup latency for Firefox
Using .init_array
/.fini_array
instead of .ctors
/.dtors
removes the need for the associated (relative) relocations, and avoids the backwards disk seeks on startup (since while .ctors
are processed backwards, .init_array
is processed forward).
Transition from .ctors
to .init_array
The mainline versions of both GNU ld
and gold
now put .ctors
sections into .init_array
sections, and put .dtors
sections into .fini_array
sections.
Comment: Probably introduced with GCC 4.7.
ARM
ARM EABI has been using .init_array
from 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: ...").