diff options
| -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) | 
