mirror of
https://github.com/topjohnwu/crt0.git
synced 2024-11-26 21:00:42 +00:00
Proper exit implementation
This commit is contained in:
parent
88c7161c55
commit
bf9f9b3cc3
@ -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
41
misc.c
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user