SPRAB89A September 2011 – March 2014
The System V ABI specifies an initialization sequence for executables and shared objects through which functions such as constructors for global objects can be called prior to calling main. Similarly, there is a mechanism for defining functions to be called after main returns. These mechanisms use tables of function pointers marked by DT_INIT* and DT_FINI* dynamic tags.
Section 3.3.5 of the GC++ ABI augments the termination mechanism to enable C++ programs to properly register destructors to be called when a shared object is unloaded before the program that uses it terminates. The mechanism uses an API function in the C++ compiler support library called _ _cxa_atexit, which is called as follows:
__cxa_atexit(dtor, obj, &__dso_handle);
(Here dtor is a pointer to the destructor function and obj is a pointer to the object.)
The third argument, _ _dso_handle, is a unique address that identifies the shared object. The C6000 ABI defines its value to be the address of the module's near-DP segment.
Another function, _ _cxa_finalize, implements calls to the registered functions when the shared object is unloaded. This function is called as follows:
__cxa_finalize(&__dso_handle);
The linker must arrange for this call to occur as the first termination action, typically via the DT_FINI* table. Since _ _cxa_finalize has an argument, and DT_FINI functions are called without arguments, the linker must generate a nullary wrapper function for the call.
To summarize the requirements for this convention, the static linker is responsible for:
These requirements apply when generating any executable or shared object containing a call to _ _cxa_atexit.