LibC: implement and call __cxa_finalize() on exit()

This allows global destructors to be actually called
This commit is contained in:
Bananymous 2023-10-30 11:10:08 +02:00
parent f05b9a6877
commit bc1d1bf919
3 changed files with 39 additions and 24 deletions

View File

@ -1,35 +1,37 @@
#include <icxxabi.h>
#define ATEXIT_MAX_FUNCS 128 #define ATEXIT_MAX_FUNCS 128
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned uarch_t;
struct atexit_func_entry_t struct atexit_func_entry_t
{ {
/* void (*destructor)(void*);
* Each member is at least 4 bytes large. Such that each entry is 12bytes. void* data;
* 128 * 12 = 1.5KB exact. void* dso_handle;
**/
void (*destructor_func)(void *);
void *obj_ptr;
void *dso_handle;
}; };
atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS]; static atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
uarch_t __atexit_func_count = 0; static int __atexit_func_count = 0;
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso) int __cxa_atexit(void (*func)(void*), void* data, void* dso_handle)
{ {
if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {return -1;}; if (__atexit_func_count >= ATEXIT_MAX_FUNCS)
__atexit_funcs[__atexit_func_count].destructor_func = f; return -1;;
__atexit_funcs[__atexit_func_count].obj_ptr = objptr; __atexit_funcs[__atexit_func_count].destructor = func;
__atexit_funcs[__atexit_func_count].dso_handle = dso; __atexit_funcs[__atexit_func_count].data = data;
__atexit_funcs[__atexit_func_count].dso_handle = dso_handle;
__atexit_func_count++; __atexit_func_count++;
return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/ return 0;
}; };
#ifdef __cplusplus void __cxa_finalize(void* func)
}; {
#endif for (int i = __atexit_func_count - 1; i >= 0; i--)
{
if (func && func != __atexit_funcs[i].destructor)
continue;
if (__atexit_funcs[i].destructor == nullptr)
continue;
__atexit_funcs[i].destructor(__atexit_funcs[i].data);
__atexit_funcs[i].destructor = nullptr;
}
}

10
libc/include/icxxabi.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <sys/cdefs.h>
__BEGIN_DECLS
int __cxa_atexit(void (*func)(void*), void* data, void* dso_handle);
void __cxa_finalize(void* func);
__END_DECLS

View File

@ -7,6 +7,8 @@
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
#include <icxxabi.h>
extern "C" char** environ; extern "C" char** environ;
extern "C" void _fini(); extern "C" void _fini();
@ -21,6 +23,7 @@ void abort(void)
void exit(int status) void exit(int status)
{ {
fflush(nullptr); fflush(nullptr);
__cxa_finalize(nullptr);
_fini(); _fini();
_exit(status); _exit(status);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();