about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/env/__libc_start_main.c26
-rw-r--r--src/exit/exit.c16
-rw-r--r--src/internal/libc.h3
-rw-r--r--src/ldso/dynlink.c14
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)