crt: Implement standard-conforming termination support with mcfgthread
This commit implements these functions in accordance with the ISO C
standard and the Itanium C++ ABI (except for `atexit()` which behaves
in a per-module way like its old behavior, and also on Linux):
* `atexit()`, C89
* `exit()`, C89
* `__cxa_atexit()`, Itanium C++ ABI
* `_exit()`, POSIX
* `_Exit()`, C99
* `at_quick_exit()`, C99
* `quick_exit()`, C99
* `__cxa_at_quick_exit()`, GNU extension
Implementation details:
1. An object with the name `__dso_handle` is defined for each
module (EXE or DLL).
2. Per-module cleanup callbacks should be registered with
`__MCF_cxa_atexit()` or `__MCF_cxa_at_quick_exit()`, passing
`&__dso_handle` as its third argument.
3. When a process calls `exit()` or returns from `main()`,
`__MCF_cxa_finalize(NULL)` is called, which executes all
callbacks registered with `__MCF_cxa_atexit()` in reverse
order.
4. When a DLL is unloaded neither by calling `exit()` nor by
returning from `main()` (in other words, by `FreeLibrary()`),
`__MCF_cxa_finalize(&__dso_handle)`, which executes all
callbacks registered with `__MCF_cxa_atexit()` with the same
DSO handle in reverse order. Callbacks that have been
registered with `__MCF_cxa_at_quick_exit()` are deleted.
5. All standard I/O streams are flushed before the process
terminates.
Signed-off-by: LIU Hao <lh_mouse@126.com>
6 files changed