xref: /dflybsd-src/lib/csu/common/initfini.c (revision 88cb131568c551d47f7b04eea6931bff5663ba43)
179dc5732SJohn Marino /*-
279dc5732SJohn Marino  * Copyright 2012 Konstantin Belousov <kib@FreeBSD.org>
379dc5732SJohn Marino  * All rights reserved.
479dc5732SJohn Marino  *
579dc5732SJohn Marino  * Redistribution and use in source and binary forms, with or without
679dc5732SJohn Marino  * modification, are permitted provided that the following conditions
779dc5732SJohn Marino  * are met:
879dc5732SJohn Marino  * 1. Redistributions of source code must retain the above copyright
979dc5732SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1079dc5732SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1179dc5732SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1279dc5732SJohn Marino  *    documentation and/or other materials provided with the distribution.
1379dc5732SJohn Marino  *
1479dc5732SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1579dc5732SJohn Marino  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1679dc5732SJohn Marino  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1779dc5732SJohn Marino  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1879dc5732SJohn Marino  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1979dc5732SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2079dc5732SJohn Marino  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2179dc5732SJohn Marino  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2279dc5732SJohn Marino  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2379dc5732SJohn Marino  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2479dc5732SJohn Marino  */
2579dc5732SJohn Marino 
26e2d7e866SJohn Marino #include "notes.h"
27e2d7e866SJohn Marino 
2879dc5732SJohn Marino extern int main(int, char **, char **);
2979dc5732SJohn Marino 
3079dc5732SJohn Marino extern void (*__preinit_array_start []) (int, char **, char **) __dso_hidden;
3179dc5732SJohn Marino extern void (*__preinit_array_end   []) (int, char **, char **) __dso_hidden;
3279dc5732SJohn Marino extern void (*__init_array_start    []) (int, char **, char **) __dso_hidden;
3379dc5732SJohn Marino extern void (*__init_array_end      []) (int, char **, char **) __dso_hidden;
3479dc5732SJohn Marino extern void (*__fini_array_start    []) (void) __dso_hidden;
3579dc5732SJohn Marino extern void (*__fini_array_end      []) (void) __dso_hidden;
3679dc5732SJohn Marino extern void _fini(void);
3779dc5732SJohn Marino extern void _init(void);
3879dc5732SJohn Marino 
3979dc5732SJohn Marino extern int _DYNAMIC;
4079dc5732SJohn Marino #pragma weak _DYNAMIC
4179dc5732SJohn Marino 
4279dc5732SJohn Marino char **environ;
4379dc5732SJohn Marino const char *__progname = "";
4479dc5732SJohn Marino 
45e2d7e866SJohn Marino static void
finalizer(void)46e2d7e866SJohn Marino finalizer(void)
47e2d7e866SJohn Marino {
48e2d7e866SJohn Marino 	void (*fn)(void);
49e2d7e866SJohn Marino 	size_t array_size, n;
50e2d7e866SJohn Marino 
51e2d7e866SJohn Marino 	array_size = __fini_array_end - __fini_array_start;
52e2d7e866SJohn Marino 	for (n = array_size; n > 0; n--) {
53e2d7e866SJohn Marino 		fn = __fini_array_start[n - 1];
54e2d7e866SJohn Marino 		if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1)
55e2d7e866SJohn Marino 			(fn)();
56e2d7e866SJohn Marino 	}
57e2d7e866SJohn Marino 	_fini();
58e2d7e866SJohn Marino }
59e2d7e866SJohn Marino 
60e2d7e866SJohn Marino static inline void
handle_static_init(int argc,char ** argv,char ** env)61e2d7e866SJohn Marino handle_static_init(int argc, char **argv, char **env)
62e2d7e866SJohn Marino {
63e2d7e866SJohn Marino 	void (*fn)(int, char **, char **);
64e2d7e866SJohn Marino 	size_t array_size, n;
65e2d7e866SJohn Marino 
66e2d7e866SJohn Marino 	if (&_DYNAMIC != NULL)
67e2d7e866SJohn Marino 		return;
68e2d7e866SJohn Marino 
69e2d7e866SJohn Marino 	atexit(finalizer);
70e2d7e866SJohn Marino 
71e2d7e866SJohn Marino 	array_size = __preinit_array_end - __preinit_array_start;
72e2d7e866SJohn Marino 	for (n = 0; n < array_size; n++) {
73e2d7e866SJohn Marino 		fn = __preinit_array_start[n];
74e2d7e866SJohn Marino 		if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1)
75e2d7e866SJohn Marino 			fn(argc, argv, env);
76e2d7e866SJohn Marino 	}
77e2d7e866SJohn Marino 	_init();
78e2d7e866SJohn Marino 	array_size = __init_array_end - __init_array_start;
79e2d7e866SJohn Marino 	for (n = 0; n < array_size; n++) {
80e2d7e866SJohn Marino 		fn = __init_array_start[n];
81e2d7e866SJohn Marino 		if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1)
82e2d7e866SJohn Marino 			fn(argc, argv, env);
83e2d7e866SJohn Marino 	}
84e2d7e866SJohn Marino }
85e2d7e866SJohn Marino 
8679dc5732SJohn Marino static inline void
handle_argv(int argc,char * argv[],char ** env)87*a834075aSJohn Marino handle_argv(int argc, char *argv[], char **env)
8879dc5732SJohn Marino {
8979dc5732SJohn Marino 	const char *s;
9079dc5732SJohn Marino 
91*a834075aSJohn Marino 	if (environ == NULL)
92*a834075aSJohn Marino 		environ = env;
93*a834075aSJohn Marino 	if (argc > 0 && argv[0] != NULL) {
94*a834075aSJohn Marino 		__progname = argv[0];
9579dc5732SJohn Marino 		for (s = __progname; *s != '\0'; s++) {
9679dc5732SJohn Marino 			if (*s == '/')
9779dc5732SJohn Marino 				__progname = s + 1;
9879dc5732SJohn Marino                 }
9979dc5732SJohn Marino 	}
100*a834075aSJohn Marino }
10179dc5732SJohn Marino 
102e2d7e866SJohn Marino static const struct {
103e2d7e866SJohn Marino 	int32_t	namesz;
104e2d7e866SJohn Marino 	int32_t	descsz;
105e2d7e866SJohn Marino 	int32_t	type;
106e2d7e866SJohn Marino 	char	name[sizeof(NOTE_VENDOR)];
107e2d7e866SJohn Marino 	uint32_t desc;
108e2d7e866SJohn Marino } crt_noinit_tag __attribute__ ((section (NOTE_SECTION),
109e2d7e866SJohn Marino     aligned(4))) __attribute__ ((used)) = {
110e2d7e866SJohn Marino 	.namesz = sizeof(NOTE_VENDOR),
111e2d7e866SJohn Marino 	.descsz = sizeof(uint32_t),
112e2d7e866SJohn Marino 	.type = CRT_NOINIT_NOTETYPE,
113e2d7e866SJohn Marino 	.name = NOTE_VENDOR,
114e2d7e866SJohn Marino 	.desc = 0
115e2d7e866SJohn Marino };
116