C++ initialization, construction and
destruction

The C++ Standard places certain requirements on the construction
and destruction of objects with static storage duration.

The ARM C++ compiler uses the .init_array area
to achieve this. This is a const data array of self-relative
pointers to functions. For example, you might have the following
C++ translation unit, contained in the file test.cpp:

This pseudocode is for illustration only. To see the code
that is generated, compile the C++ source code with armcc-c--cpp-S.

The linker collects each .init_array from
the various translation units together. It is important that the .init_array is
accumulated in the same order.

The library routine __cpp_initialize__aeabi_ is
called from the C library startup code, __rt_lib_init,
before main. __cpp_initialize__aeabi_ walks
through the .init_array calling each function
in turn. On exit, __rt_lib_shutdown calls __cxa_finalize.

Usually, there is at most one function for T::T(),
mangled name _ZN1TC1Ev, one function for T::~T(),
mangled name _ZN1TD1Ev, one __sti__ function,
and four bytes of .init_array for each translation
unit. The mangled name for the function f() is _Z1fv.
There is no way to determine the initialization order between translation
units.

Function-local static objects with destructors are also handled
using __aeabi_atexit.

.init_array sections must be placed
contiguously within the same region for their base and limit symbols
to be accessible. If they are not, the linker generates an error.