summaryrefslogtreecommitdiff
path: root/lib/csu
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2018-12-21 05:45:43 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2018-12-21 05:45:43 +0000
commit889f48af5f9aeb6e1669018879d4ec16eecb20fe (patch)
tree5d73b49cf7696cc88e063678dd4adcb684908e16 /lib/csu
parente55bf67773356778a0c58fad5e0ae358f09df53b (diff)
Add support for {preinit,init,fini}_array sections in static binaries
ok kettenis@
Diffstat (limited to 'lib/csu')
-rw-r--r--lib/csu/crt0.c22
-rw-r--r--lib/csu/crtbegin.c12
-rw-r--r--lib/csu/extern.h2
3 files changed, 34 insertions, 2 deletions
diff --git a/lib/csu/crt0.c b/lib/csu/crt0.c
index 0e8c7a5f5ee..0ffccaf312c 100644
--- a/lib/csu/crt0.c
+++ b/lib/csu/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.10 2017/01/21 04:14:19 guenther Exp $ */
+/* $OpenBSD: crt0.c,v 1.11 2018/12/21 05:45:42 guenther Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou
@@ -67,14 +67,34 @@ MD_CRT0_START;
#endif
#endif
+extern __dso_hidden initarray_f __preinit_array_start[],
+ __preinit_array_end[], __init_array_start[], __init_array_end[];
+
+extern char __csu_do_fini_array __dso_hidden;
+
void
___start(MD_START_ARGS)
{
+ size_t size, i;
char ***environp;
#ifdef MD_START_SETUP
MD_START_SETUP
#endif
+#ifndef RCRT0
+ if (cleanup == NULL) {
+#endif
+ size = __preinit_array_end - __preinit_array_start;
+ for (i = 0; i < size; i++)
+ __preinit_array_start[i](argc, argv, envp, NULL);
+ size = __init_array_end - __init_array_start;
+ for (i = 0; i < size; i++)
+ __init_array_start[i](argc, argv, envp, NULL);
+ __csu_do_fini_array = 1;
+#ifndef RCRT0
+ }
+#endif
+
environp = _csu_finish(argv, envp, cleanup);
#ifdef MCRT0
diff --git a/lib/csu/crtbegin.c b/lib/csu/crtbegin.c
index b6f5c7fe373..8290150592b 100644
--- a/lib/csu/crtbegin.c
+++ b/lib/csu/crtbegin.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crtbegin.c,v 1.24 2017/02/19 21:39:32 guenther Exp $ */
+/* $OpenBSD: crtbegin.c,v 1.25 2018/12/21 05:45:42 guenther Exp $ */
/* $NetBSD: crtbegin.c,v 1.1 1996/09/12 16:59:03 cgd Exp $ */
/*
@@ -145,6 +145,9 @@ __do_init(void)
}
}
+char __csu_do_fini_array __dso_hidden = 0;
+extern __dso_hidden init_f __fini_array_start[], __fini_array_end[];
+
void
__do_fini(void)
{
@@ -156,6 +159,13 @@ __do_fini(void)
* Call global destructors.
*/
__dtors();
+
+ if (__csu_do_fini_array) {
+ size_t i = __fini_array_end - __fini_array_start;
+ while (i-- > 0)
+ __fini_array_start[i]();
+ }
+
}
}
diff --git a/lib/csu/extern.h b/lib/csu/extern.h
index d2087e0fa4e..5cc17413c8a 100644
--- a/lib/csu/extern.h
+++ b/lib/csu/extern.h
@@ -17,6 +17,8 @@
void __init(void) __dso_hidden;
int main(int argc, char *argv[], char *envp[]);
+struct dl_cb;
+typedef void (*initarray_f)(int, char **, char **, const struct dl_cb *);
typedef void (*init_f)(void);
/*