Proper exit implementation

This commit is contained in:
topjohnwu 2024-04-15 16:33:29 -07:00
parent 88c7161c55
commit bf9f9b3cc3
3 changed files with 42 additions and 9 deletions

View File

@ -3,18 +3,15 @@
char **environ;
extern void _exit(int);
extern void exit(int);
extern void __init_stdio(void);
typedef void init_func_t(int, char*[], char*[]);
typedef void fini_func_t(void);
extern init_func_t *__preinit_array_start[];
extern init_func_t *__preinit_array_end[];
extern init_func_t *__init_array_start[];
extern init_func_t *__init_array_end[];
extern fini_func_t *__fini_array_start[];
extern fini_func_t *__fini_array_end[];
static void call_array(init_func_t **start, init_func_t **end, int argc, char *argv[], char *envp[]) {
unsigned long count = end - start;
@ -75,7 +72,7 @@ void _start_c(long *sp) {
call_array(__init_array_start, __init_array_end, argc, argv, envp);
/* go to application */
_exit(__real_main(argc, argv, envp));
exit(__real_main(argc, argv, envp));
}
unsigned long getauxval(unsigned long type) {

41
misc.c
View File

@ -181,11 +181,48 @@ void __wrap_abort_message(const char* format, ...) {
abort();
}
// Don't care about C++ global destructors
int __cxa_atexit(void (*func) (void *), void * arg, void * dso_handle) {
typedef struct at_exit_func {
void *arg;
void (*func)(void*);
} at_exit_func;
static int at_exit_cap = 0;
static int at_exit_sz = 0;
static at_exit_func *at_exit_list = NULL;
int __cxa_atexit(void (*func)(void *), void *arg, void *dso_handle) {
if (at_exit_sz == at_exit_cap) {
at_exit_cap = at_exit_cap ? at_exit_sz * 2 : 16;
at_exit_list = realloc(at_exit_list, at_exit_cap * sizeof(at_exit_func));
}
at_exit_list[at_exit_sz].func = func;
at_exit_list[at_exit_sz].arg = arg;
++at_exit_sz;
return 0;
}
typedef void fini_func_t(void);
extern fini_func_t *__fini_array_start[];
extern fini_func_t *__fini_array_end[];
void exit(int status) {
// Call registered at_exit functions in reverse
for (int i = at_exit_sz - 1; i >= 0; --i) {
at_exit_list[i].func(at_exit_list[i].arg);
}
fini_func_t** array = __fini_array_start;
size_t count = __fini_array_end - __fini_array_start;
// Call fini functions in reverse order
while (count-- > 0) {
fini_func_t* function = array[count];
(*function)();
}
_exit(status);
}
// Emulate pthread functions
typedef struct key_data {

View File

@ -33,7 +33,6 @@ __asm__(".global " #from " \n " #from " = " #to)
#define EXPORT_SYMBOL(name) \
SYMBOL_ALIAS(name, sys_##name)
EXPORT_SYMBOL(_exit);
EXPORT_SYMBOL(openat);
EXPORT_SYMBOL(close);
EXPORT_SYMBOL(read);
@ -70,7 +69,7 @@ EXPORT_SYMBOL(execve);
EXPORT_SYMBOL(getdents64);
EXPORT_SYMBOL(clock_gettime);
SYMBOL_ALIAS(exit, _exit);
SYMBOL_ALIAS(_exit, sys_exit_group);
SYMBOL_ALIAS(openat64, openat);
SYMBOL_ALIAS(stat64, stat);
SYMBOL_ALIAS(lstat64, lstat);