[libc-commits] [libc] [libc][stdlib] initial support for __cxa_finalize (PR #85865)

via libc-commits libc-commits at lists.llvm.org
Tue Mar 19 13:47:34 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Nick Desaulniers (nickdesaulniers)

<details>
<summary>Changes</summary>

I'm trying to break up the pieces of supporting __cxa_finalize into smaller
commits. Provide this symbol first, and make use of it from exit.

Next will be to store __dso_handle, then finally to only run callbacks that
were registered from a specific dso.

Link: #<!-- -->85651
Link: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor


---
Full diff: https://github.com/llvm/llvm-project/pull/85865.diff


2 Files Affected:

- (modified) libc/src/stdlib/atexit.cpp (+19-12) 
- (modified) libc/src/stdlib/exit.cpp (+3-5) 


``````````diff
diff --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp
index 741ea4f25103ac..fa072b2fdf8d09 100644
--- a/libc/src/stdlib/atexit.cpp
+++ b/libc/src/stdlib/atexit.cpp
@@ -55,14 +55,10 @@ void stdc_at_exit_func(void *payload) {
   reinterpret_cast<StdCAtExitCallback *>(payload)();
 }
 
-} // namespace
-
-namespace internal {
-
 void call_exit_callbacks() {
   handler_list_mtx.lock();
   while (!exit_callbacks.empty()) {
-    auto unit = exit_callbacks.back();
+    AtExitUnit &unit = exit_callbacks.back();
     exit_callbacks.pop_back();
     handler_list_mtx.unlock();
     unit.callback(unit.payload);
@@ -71,20 +67,31 @@ void call_exit_callbacks() {
   ExitCallbackList::destroy(&exit_callbacks);
 }
 
-} // namespace internal
-
-static int add_atexit_unit(const AtExitUnit &unit) {
+int add_atexit_unit(const AtExitUnit &unit) {
   MutexLock lock(&handler_list_mtx);
-  if (!exit_callbacks.push_back(unit))
-    return -1;
-  return 0;
+  if (exit_callbacks.push_back(unit))
+    return 0;
+  return -1;
 }
 
+} // namespace
+
+extern "C" {
+
 // TODO: Handle the last dso handle argument.
-extern "C" int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
+int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
   return add_atexit_unit({callback, payload});
 }
 
+// TODO: Handle the dso handle argument. call_exit_callbacks should only invoke
+// the callbacks from this DSO. Requires adding support for __dso_handle.
+void __cxa_finalize(void *dso) {
+  if (!dso)
+    call_exit_callbacks();
+}
+
+} // extern "C"
+
 LLVM_LIBC_FUNCTION(int, atexit, (StdCAtExitCallback * callback)) {
   return add_atexit_unit(
       {&stdc_at_exit_func, reinterpret_cast<void *>(callback)});
diff --git a/libc/src/stdlib/exit.cpp b/libc/src/stdlib/exit.cpp
index cc5ae6648d11f2..e754b34e46985a 100644
--- a/libc/src/stdlib/exit.cpp
+++ b/libc/src/stdlib/exit.cpp
@@ -10,14 +10,12 @@
 #include "src/__support/OSUtil/quick_exit.h"
 #include "src/__support/common.h"
 
-namespace LIBC_NAMESPACE {
+extern "C" void __cxa_finalize(void *);
 
-namespace internal {
-void call_exit_callbacks();
-}
+namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(void, exit, (int status)) {
-  internal::call_exit_callbacks();
+  __cxa_finalize(nullptr);
   quick_exit(status);
   __builtin_unreachable();
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/85865


More information about the libc-commits mailing list