-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
doc: Update according to build system changes
- Loading branch information
Showing
3 changed files
with
150 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,25 @@ | ||
These are patches that I use to build GCC 11 with mcfgthread support. | ||
|
||
Normally, mingw-w64 CRT performs per-thread cleanup upon receipt of `DLL_PROCESS_DETACH` in a TLS callback (of an EXE) or the `DllMainCRTStartup()` function (of a DLL). There are some major issues in this approach: | ||
Normally, mingw-w64 CRT performs per-thread cleanup upon receipt of | ||
`DLL_PROCESS_DETACH` in a TLS callback (of an EXE) or the `DllMainCRTStartup()` | ||
function (of a DLL). There are some major issues in this approach: | ||
|
||
1. These callbacks are invoked after Windows has terminated all the other threads. If another thread is terminated while it has locked a mutex, the mutex will never get unlocked. If a destructor of a static object or a callback that has been registered with `atexit()` attempts to acquire the exact mutex, deadlocks can occur. | ||
2. These callbacks are still invoked if the user calls `_Exit()` or `quick_exit()`, such as [in LLVM](https://reviews.llvm.org/D102944). As specified by the C++ standard, they shall not be called. | ||
3. Per-thread cleanup may be performed after destructors of static objects. The C++ standard does not allow this behavior. | ||
1. These callbacks are invoked after Windows has terminated all the other | ||
threads. If another thread is terminated while it has locked a mutex, the | ||
mutex will never get unlocked. If a destructor of a static object or a | ||
callback that has been registered with `atexit()` attempts to acquire the | ||
exact mutex, deadlocks can occur. | ||
2. These callbacks are still invoked if the user calls `_Exit()` or | ||
`quick_exit()`, such as [in LLVM](https://reviews.llvm.org/D102944). As | ||
specified by the C++ standard, they shall not be called. | ||
3. Per-thread cleanup may be performed after destructors of static objects. The | ||
C++ standard does not allow this behavior. | ||
|
||
GCC uses `atexit()` to register destructors for static objects. Therefore, the CRT has to be modified to forward such calls to `__MCF_cxa_atexit()`, passing the address of the module-specific `__dso_handle` as their third arguments. The modified CRT also forwards calls to `exit()`, `_Exit()`, `_exit()` and `quick_exit()` to standard-conforming ones in mcfgthread, which eventually calls `TerminateProcess()` instead of `ExitProcess()`, to address such issues. Per-thread and process cleanup is performed by `__cxa_finalize()`, in accordance with the Itanium ABI. | ||
GCC uses `atexit()` to register destructors for static objects. Therefore, | ||
the CRT has to be modified to forward such calls to `__MCF_cxa_atexit()`, | ||
passing the address of the module-specific `__dso_handle` as their third | ||
arguments. The modified CRT also forwards calls to `exit()`, `_Exit()`, | ||
`_exit()` and `quick_exit()` to standard-conforming ones in mcfgthread, which | ||
eventually calls `TerminateProcess()` instead of `ExitProcess()`, to address | ||
such issues. Per-thread and process cleanup is performed by `__cxa_finalize()`, | ||
in accordance with the Itanium ABI. |