forked from Bananymous/banan-os
LibC: implement and call __cxa_finalize() on exit()
This allows global destructors to be actually called
This commit is contained in:
parent
f05b9a6877
commit
bc1d1bf919
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue