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