// for memcpy() #include #include #include #include #include struct ExitHandler { void (*function)(void *); void *argument; void *dsoHandle; }; using ExitQueue = frg::vector; ExitQueue &getExitQueue() { // use frg::eternal to prevent the compiler from scheduling the destructor // by generating a call to __cxa_atexit(). static frg::eternal singleton(getAllocator()); return singleton.get(); } extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *handle) { ExitHandler handler; handler.function = function; handler.argument = argument; handler.dsoHandle = handle; getExitQueue().push(handler); return 0; } void __mlibc_do_finalize() { ExitQueue &eq = getExitQueue(); for(size_t i = eq.size(); i > 0; i--) { auto handler = &eq[i - 1]; handler->function(handler->argument); } }