As described in the ItaniumŪ C++ ABI, the C runtime library shall maintain a list of termination function entries containing the following information:
A pointer to a termination function.
An operand to be passed to the function.
A handle identifying the home shared library of the entry.
The list is populated by entries of two kinds:
Destructors of global (or local static) C++ objects that require destruction on exit.
Functions registered by the user with atexit().
In the former case an entry consists of a pointer to the destructor, a pointer to the corresponding object and a handle for the home shared library of the object. In the latter case the pointer to the function is the pointer passed to atexit(), while the other pointers are NULL.
When __cxa_finalize(d) is called, it shall walk the termination function list, calling each in turn if d matches the handle of the termination function entry. If d is NULL, it shall call all the termination funtions. Multiple calls to __cxa_finalize shall not result in calling termination function entries multiple times; the implementation may either remove entries or mark them finished. The termination functions shall always be called in the reverse order of their registration (i.e. the most recently registered function shall be called first).
An application shall not call __cxa_finalize() directly. The implementation shall arrange for__cxa_finalize() to be called during early shared library unload (e.g. dlclose()) with a handle to the shared library. When the main program calls exit, the implementation shall cause any remaining __cxa_atexit-registered functions to be called, either by calling __cxa_finalize(NULL), or by walking the registration list itself.
__cxa_finalize() is not in the source standard; it is only in the binary standard.