aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-11-30 17:56:23 -0500
committerRich Felker <dalias@aerifal.cx>2012-11-30 17:56:23 -0500
commita7936f61b23100ac32f51776c5b3e52452c7598c (patch)
treef389101a0cd75932cf5b027d99d49e38233eabe7
parent1c322f2f0a9173a3ae8c8bfa12d5d8e92fb5d0ab (diff)
downloadmusl-a7936f61b23100ac32f51776c5b3e52452c7598c.zip
musl-a7936f61b23100ac32f51776c5b3e52452c7598c.tar.gz
musl-a7936f61b23100ac32f51776c5b3e52452c7598c.tar.bz2
fix ordering of shared library ctors with respect to libc init
previously, shared library constructors were being called before important internal things like the environment (extern char **environ) and hwcap flags (needed for sjlj to work right with float on arm) were initialized in __libc_start_main. rather than trying to have to dynamic linker make sure this stuff all gets initialized right, I've opted to just defer calling shared library constructors until after the main program's entry point is reached. this also fixes the order of ctors to be the exact reverse of dtors, which is a desirable property and possibly even mandated by some languages. the main practical effect of this change is that shared libraries calling getenv from ctors will no longer fail.
-rw-r--r--src/env/__libc_start_main.c5
-rw-r--r--src/ldso/dynlink.c9
2 files changed, 11 insertions, 3 deletions
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index ee10b0d..04a454e 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -3,6 +3,7 @@
void __init_tls(size_t *);
void __init_security(size_t *);
+void __init_ldso_ctors(void);
#define AUX_CNT 38
@@ -37,6 +38,10 @@ int __libc_start_main(
/* Execute constructors (static) linked into the application */
if (init) init(argc, argv, envp);
+#ifdef SHARED
+ __init_ldso_ctors();
+#endif
+
/* Pass control to to application */
exit(main(argc, argv, envp));
return 0;
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index c436b88..d564b8f 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -999,13 +999,16 @@ void *__dynlink(int argc, char **argv)
if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]);
- atexit(do_fini);
- do_init_fini(tail);
-
errno = 0;
return (void *)aux[AT_ENTRY];
}
+void __init_ldso_ctors(void)
+{
+ atexit(do_fini);
+ do_init_fini(tail);
+}
+
void *dlopen(const char *file, int mode)
{
struct dso *volatile p, *orig_tail, *next;