diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/env/__libc_start_main.c | 26 | ||||
-rw-r--r-- | src/exit/exit.c | 16 | ||||
-rw-r--r-- | src/internal/libc.h | 3 | ||||
-rw-r--r-- | src/ldso/dynlink.c | 14 |
4 files changed, 33 insertions, 26 deletions
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c index aef9f9ec..2a8698bb 100644 --- a/src/env/__libc_start_main.c +++ b/src/env/__libc_start_main.c @@ -5,6 +5,13 @@ void __init_tls(size_t *); void __init_security(size_t *); void __init_ldso_ctors(void); +#ifndef SHARED +static void dummy() {} +weak_alias(dummy, _init); +extern void (*const __init_array_start)() __attribute__((weak)); +extern void (*const __init_array_end)() __attribute__((weak)); +#endif + #define AUX_CNT 38 extern size_t __hwcap, __sysinfo; @@ -29,23 +36,16 @@ void __init_libc(char **envp, char *pn) __init_security(aux); } -int __libc_start_main( - int (*main)(int, char **, char **), int argc, char **argv, - int (*init)(int, char **, char **), void (*fini)(void), - void (*ldso_fini)(void)) +int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv) { char **envp = argv+argc+1; +#ifndef SHARED __init_libc(envp, argv[0]); - - libc.ldso_fini = ldso_fini; - libc.fini = fini; - - /* Execute constructors (static) linked into the application */ - if (init) init(argc, argv, envp); - -#ifdef SHARED - __init_ldso_ctors(); + _init(); + uintptr_t a = (uintptr_t)&__init_array_start; + for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)())) + (*(void (**)())a)(); #endif /* Pass control to to application */ diff --git a/src/exit/exit.c b/src/exit/exit.c index e4932b5b..f259c982 100644 --- a/src/exit/exit.c +++ b/src/exit/exit.c @@ -14,6 +14,12 @@ weak_alias(dummy, __funcs_on_exit); weak_alias(dummy, __flush_on_exit); weak_alias(dummy, __seek_on_exit); +#ifndef SHARED +weak_alias(dummy, _fini); +extern void (*const __fini_array_start)() __attribute__((weak)); +extern void (*const __fini_array_end)() __attribute__((weak)); +#endif + _Noreturn void exit(int code) { static int lock; @@ -22,8 +28,14 @@ _Noreturn void exit(int code) while (a_swap(&lock, 1)) __syscall(SYS_pause); __funcs_on_exit(); - if (libc.fini) libc.fini(); - if (libc.ldso_fini) libc.ldso_fini(); + +#ifndef SHARED + uintptr_t a = (uintptr_t)&__fini_array_end; + for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)())) + (*(void (**)())(a-sizeof(void(*)())))(); + _fini(); +#endif + __flush_on_exit(); __seek_on_exit(); diff --git a/src/internal/libc.h b/src/internal/libc.h index c9416f07..c8fbe3fd 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -9,9 +9,6 @@ struct __libc { int threaded; int secure; size_t *auxv; - int (*atexit)(void (*)(void)); - void (*fini)(void); - void (*ldso_fini)(void); volatile int threads_minus_1; int canceldisable; FILE *ofl_head; diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 829696ff..3a0bf95d 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -91,6 +91,7 @@ struct symdef { void __init_ssp(size_t *); void *__install_initial_tls(void *); +void __init_libc(char **, char *); static struct dso *head, *tail, *ldso, *fini_head; static char *env_path, *sys_path, *r_path; @@ -841,6 +842,7 @@ void *__dynlink(int argc, char **argv) char *env_preload=0; size_t vdso_base; size_t *auxv; + char **envp = argv+argc+1; /* Find aux vector just past environ[] */ for (i=argc+1; argv[i]; i++) @@ -953,7 +955,6 @@ void *__dynlink(int argc, char **argv) tls_align = MAXP2(tls_align, app->tls_align); } app->global = 1; - app->constructed = 1; decode_dyn(app); /* Attach to vdso, if provided by the kernel */ @@ -1038,15 +1039,12 @@ void *__dynlink(int argc, char **argv) _dl_debug_state(); if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]); - - errno = 0; - return (void *)aux[AT_ENTRY]; -} - -void __init_ldso_ctors(void) -{ + __init_libc(envp, argv[0]); atexit(do_fini); + errno = 0; do_init_fini(tail); + + return (void *)aux[AT_ENTRY]; } void *dlopen(const char *file, int mode) |