2020-02-15 15:51:18 +01:00
|
|
|
#include <Platform/Platform.h>
|
|
|
|
|
2020-02-17 10:54:54 +01:00
|
|
|
#if 1
|
2020-02-15 15:51:18 +01:00
|
|
|
#define DBG(...) DebugLog(2, __VA_ARGS__)
|
|
|
|
#else
|
|
|
|
#define DBG(...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(__clang__)
|
|
|
|
typedef void (destructor_func_t)();
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
typedef void (destructor_func_t)(void*);
|
|
|
|
#else
|
|
|
|
# error compiler not supported
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef destructor_func_t* destructor_func_ptr_t;
|
|
|
|
|
|
|
|
struct atexit_func_entry_t
|
|
|
|
{
|
|
|
|
destructor_func_ptr_t destructor_func;
|
|
|
|
#if !defined(__clang__) && defined(__GNUC__)
|
|
|
|
void *obj_ptr;
|
|
|
|
void *dso_handle;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static atexit_func_entry_t*atexit_func_entry_array = NULL;
|
|
|
|
static UINTN atexit_func_entry_count = 0;
|
|
|
|
static UINTN atexit_func_entry_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
#if defined (__clang__)
|
|
|
|
|
|
|
|
extern "C" int atexit(destructor_func_ptr_t destructor_func)
|
|
|
|
{
|
|
|
|
DBG("atexit(%p) sizeof=%d\n", destructor_func, sizeof(atexit_func_entry_t));
|
|
|
|
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
|
|
|
|
extern "C" int __cxa_atexit(destructor_func_ptr_t destructor_func, void *objptr, void *dso)
|
|
|
|
{
|
|
|
|
DBG("atexit(%p, %p, %p, %d)\n", destructor_func, objptr, dso, sizeof(atexit_func_entry_t));
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if ( !atexit_func_entry_array )
|
|
|
|
{
|
|
|
|
DBG("atexit : allocate\n");
|
|
|
|
atexit_func_entry_array = (atexit_func_entry_t*)AllocatePool(16*sizeof(atexit_func_entry_t));
|
|
|
|
if ( !atexit_func_entry_array ) {
|
|
|
|
DBG("atexit : allocate returned NULL\n");
|
|
|
|
CpuDeadLoop();
|
|
|
|
}
|
|
|
|
atexit_func_entry_count = 0;
|
|
|
|
atexit_func_entry_size = 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (atexit_func_entry_count >= atexit_func_entry_size)
|
|
|
|
{
|
|
|
|
DBG("atexit : reallocate atexit_func_entry_array=%d\n", (UINTN)atexit_func_entry_array);
|
|
|
|
atexit_func_entry_array = (atexit_func_entry_t *)ReallocatePool(atexit_func_entry_size*sizeof(atexit_func_entry_t), (atexit_func_entry_size+16)*sizeof(atexit_func_entry_t), atexit_func_entry_array);
|
|
|
|
if ( !atexit_func_entry_array ) {
|
|
|
|
DBG("atexit : reallocate returned NULL\n");
|
|
|
|
CpuDeadLoop();
|
|
|
|
}
|
|
|
|
atexit_func_entry_size += 16;
|
|
|
|
}
|
|
|
|
atexit_func_entry_array[atexit_func_entry_count].destructor_func = destructor_func;
|
|
|
|
#if !defined(__clang__) && defined(__GNUC__)
|
|
|
|
atexit_func_entry_array[atexit_func_entry_count].obj_ptr = objptr;
|
|
|
|
atexit_func_entry_array[atexit_func_entry_count].dso_handle = dso;
|
|
|
|
#endif
|
|
|
|
atexit_func_entry_count++;
|
|
|
|
DBG("atexit : exit (atexit_func_entry_count=%d)\n", atexit_func_entry_count);
|
|
|
|
return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void destruct_globals_objects(void *f)
|
|
|
|
{
|
|
|
|
UINTN i = atexit_func_entry_count;
|
|
|
|
|
|
|
|
while (i--)
|
|
|
|
{
|
|
|
|
# if defined(__clang__)
|
|
|
|
|
|
|
|
DBG("destruct_globals_objects: idx=%d %p\n", i, atexit_func_entry_array[i].destructor_func);
|
|
|
|
(*atexit_func_entry_array[i].destructor_func)();
|
|
|
|
atexit_func_entry_array[i].destructor_func = NULL;
|
|
|
|
atexit_func_entry_count--;
|
|
|
|
|
|
|
|
# elif defined(__GNUC__)
|
|
|
|
|
|
|
|
DBG("destruct_globals_objects: idx=%d %d, %p, %p\n", i, atexit_func_entry_array[i].destructor_func, atexit_func_entry_array[i].obj_ptr, atexit_func_entry_array[i].dso_handle);
|
|
|
|
(*atexit_func_entry_array[i].destructor_func)(atexit_func_entry_array[i].obj_ptr);
|
|
|
|
atexit_func_entry_array[i].destructor_func = NULL;
|
|
|
|
atexit_func_entry_count--;
|
|
|
|
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
}
|